Initial commit

This commit is contained in:
JasonYANG170 2024-05-09 09:46:34 +08:00
commit 158a99ac4c
78 changed files with 6599 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
# Project exclude paths
/.gradle/

3
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

1
.idea/.name Normal file
View File

@ -0,0 +1 @@
My Application

6
.idea/compiler.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>

18
.idea/gradle.xml Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

6
.idea/kotlinc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.9.0" />
</component>
</project>

10
.idea/migrations.xml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

10
.idea/misc.xml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

339
LICENSE Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) 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
this service 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 make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. 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.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
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
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the 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 a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE 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.
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
convey 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> <name of author>
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 2 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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision 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, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This 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.

43
README.md Normal file
View File

@ -0,0 +1,43 @@
<div align="center">
<h1>万物互联IOT移动端</h1>
<img src="https://img.shields.io/github/license/JasonYANG170/IOT-ConnectPC?label=License&style=for-the-badge">
<img src="https://img.shields.io/github/commit-activity/w/JasonYANG170/IOT-ConnectPC?style=for-the-badge">
<img src="https://img.shields.io/github/languages/count/JasonYANG170/IOT-ConnectPC?logo=python&style=for-the-badge">
<br>
<a href="https://discord.com/invite/az3ceRmgVe"><img alt="Discord" src="https://img.shields.io/discord/978108215499816980?style=social&logo=discord&label=echosec"></a>
<br>
这是一项基于Kotlin的物联网设备Android及HarmonyOS控制终端
<br>
</div>
## 支持系统
**WebView**设备
**IOS及Mac**设备
[Windows及Linux请点此处](https://github.com/JasonYANG170/IOT-ConnectPC)
[Web及Apple设备](https://github.com/JasonYANG170/IOT-ConnectWeb)
## 功能
- ✅ MQTT协议远程设备控制
- ✅ AI Chat交互模型联动
- ✅ Web Api获取每日天气
- ✅ 智能提醒
## 支持设备
- ✅ Flowerpot智能交互花盆
- ✅ YANG SSD智显硬盘盒
- 🚧 KeyBox钥匙
- 🚧 OnlineAdmin远控器
- 🚧 AIChatBox智能助手
欢迎其他开发者对接我们的MQTT服务器

1
app/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

71
app/build.gradle.kts Normal file
View File

@ -0,0 +1,71 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("kotlin-android")
// id("kotlin-android-extensions")
id("com.google.devtools.ksp")
}
android {
namespace = "com.example.IOTsmart"
compileSdk = 34
defaultConfig {
applicationId = "com.example.IOTsmart"
minSdk = 26
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
viewBinding = true
}
}
dependencies {
implementation ("androidx.room:room-runtime:2.6.1")
implementation("io.github.cdimascio:dotenv-kotlin:6.4.1")
ksp ("androidx.room:room-compiler:2.6.1")// Kotlin 使用 kapt
implementation ("androidx.room:room-ktx:2.6.1")//Coroutines support for Room 协程操作库
//lifecycle
implementation ("androidx.lifecycle:lifecycle-extensions:2.2.0")
implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
implementation ("org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5")
implementation ("org.eclipse.paho:org.eclipse.paho.android.service:1.1.1")
implementation ("org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5")
implementation ("com.github.bumptech.glide:glide:4.15.1")
annotationProcessor ("com.github.bumptech.glide:compiler:4.12.0")
implementation("com.squareup.picasso:picasso:2.0.0")
implementation ("com.squareup.okhttp3:okhttp:4.9.1")
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.12.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.navigation:navigation-fragment-ktx:2.7.7")
implementation("androidx.navigation:navigation-ui-ktx:2.7.7")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}

21
app/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@ -0,0 +1,20 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.example.IOTsmart",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "1.0",
"outputFile": "app-release.apk"
}
],
"elementType": "File"
}

Binary file not shown.

View File

@ -0,0 +1,24 @@
package com.example.IOTsmart
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.example.myapplication", appContext.packageName)
}
}

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android11新增 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@drawable/ino1"
android:label="万物互联"
android:roundIcon="@drawable/ino1"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication"
tools:targetApi="31">
<activity
android:name=".login"
android:exported="true"/>
<activity
android:name=".Userinfo"
android:exported="true"/>
<activity
android:name=".UPDATE"
android:label="UPDATE"/>
<activity
android:name=".addActivity"
android:label="addActivity"/>
<activity
android:name=".aichat"
android:label="aichat"/>
<activity
android:name=".flowerpot"
android:label="flowerpot"/>
<!-- 这里可以添加其他配置 -->
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

8
app/src/main/assets/env Normal file
View File

@ -0,0 +1,8 @@
MQTT_URL = "tcp://"
MQTT_CLIENTID = ""
MQTT_TOPIC = ""
APP_UPGRADE_URL=""
APP_UPDATA_URL=""
APP_AICHAT_URL=""
APP_API1=""
APP_API2=""

View File

@ -0,0 +1,65 @@
package com.example.IOTsmart
import MyDatabase
import android.content.Intent
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.example.IOTsmart.R
import com.google.android.material.bottomnavigation.BottomNavigationView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
open class BaseActivity() : AppCompatActivity() {
private lateinit var myDatabase: MyDatabase
fun setupBottomNavigationView(selectedItemId: Int) {
myDatabase = MyDatabase(this)
var id = -1
GlobalScope.launch(Dispatchers.IO) {
val userList = myDatabase.retrieveData()
val filteredList = userList.filter { it.login == 0 }
if (filteredList.isNotEmpty()) {
val userData = filteredList.first()
val message = "用户ID${userData.id}\n用户名:${userData.name}\n密码:${userData.password}"
withContext(Dispatchers.Main) {
/* val alertDialog = AlertDialog.Builder(this@BaseActivity)
.setTitle("登录为0的用户信息")
.setMessage(message)
.setPositiveButton("确定", null)
.create()
alertDialog.show()
*/
id = 0
}
}
}
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom_navigation)
bottomNavigationView.selectedItemId = selectedItemId
bottomNavigationView.setOnItemSelectedListener { item ->
when (item.itemId) {
R.id.item_1 -> {
startActivity(Intent(this, MainActivity::class.java))
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
true
}
R.id.item_2 -> {
if (id == -1) {
startActivity(Intent(this, login::class.java))
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
} else {
// 修改Login字符串资源的值
startActivity(Intent(this, Userinfo::class.java))
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
}
true
}
else -> false
}
}
}
}

View File

@ -0,0 +1,30 @@
package com.example.IOTsmart
import androidx.room.Embedded
import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.room.Relation
@Entity
data class Driver(
@PrimaryKey val DiverId: String,
val Driverbyuserid: String,
val Drivername: String
)
@Entity
data class Userx(
@PrimaryKey val Userid: String,
val Name: String,
val Password: String,
val LoginStats: Int,
val Image: Int)
data class Userbydriver(
@Embedded val User: Userx,
@Relation(
parentColumn = "Userid",
entityColumn = "Driverbyuserid"
)
val Driver: List<Driver>
)

View File

@ -0,0 +1,401 @@
import DBHelper.Companion.COLUMN_ID
import DBHelper.Companion.TABLE_NAME
import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import com.example.IOTsmart.User
class MyDatabase(public val context: Context) {
private val dbHelper = DBHelper(context)
// 根据登录号获取图片
fun getImgByLogin(login: Int): Int {
// 获取可读的数据库
val db = dbHelper.readableDatabase
// 定义查询的列
val columns = arrayOf(DBHelper.COLUMN_img)
// 定义查询条件
val selection = "${DBHelper.COLUMN_login} = ?"
// 定义查询参数
val selectionArgs = arrayOf(login.toString())
// 执行查询
val cursor = db.query(DBHelper.TABLE_NAME, columns, selection, selectionArgs, null, null, null)
// 初始化图片
var img = 0
// 如果查询到结果
if (cursor.moveToFirst()) {
// 获取图片列的索引
val imgIndex = cursor.getColumnIndex(DBHelper.COLUMN_img)
// 获取图片
img = cursor.getInt(imgIndex)
}
// 关闭游标
cursor.close()
// 关闭数据库
db.close()
return img
}
fun updateLoginValues() {//已在ROOM实现
//获取可写的数据库
val db = dbHelper.writableDatabase
//创建一个ContentValues对象
val values = ContentValues()
//将DBHelper.COLUMN_login的值设置为-1
values.put(DBHelper.COLUMN_login, -1)
//定义whereClause用于更新数据的条件
val whereClause = "${DBHelper.COLUMN_login} = ?"
//定义whereArgs用于更新数据的参数
val whereArgs = arrayOf("0")
//更新数据
db.update(DBHelper.TABLE_NAME, values, whereClause, whereArgs)
//关闭数据库
db.close()
}
//更新用户登录状态
fun updateUserLoginStatus(user: String?,now:Int) {//已在ROOM实现
//获取可写的数据库
val db = dbHelper.writableDatabase
//创建一个ContentValues对象
val values = ContentValues()
//将登录状态更新到数据库
values.put(DBHelper.COLUMN_login, now)
//定义更新条件
val whereClause = "${DBHelper.COLUMN_NAME} = ?"
//定义更新参数
val whereArgs = arrayOf(user)
//更新数据
db.update(DBHelper.TABLE_NAME, values, whereClause, whereArgs)
//关闭数据库
db.close()
}
//更新图片
fun updateimg(img:Int) {
//获取可写的数据库
val db = dbHelper.writableDatabase
//创建一个ContentValues对象
val values = ContentValues()
//将img的值放入ContentValues对象中
values.put(DBHelper.COLUMN_img, img)
//定义whereClause用于更新数据
val whereClause = "${DBHelper.COLUMN_login} = ?"
//定义whereArgs用于更新数据
val whereArgs = arrayOf("0")
//更新数据
db.update(DBHelper.TABLE_NAME, values, whereClause, whereArgs)
//关闭数据库
db.close()
}
// 向数据库中插入数据
fun insertData(id: Int, name: String?,password: String?,login:Int,img:Int) {//已在ROOM实现
// 创建ContentValues对象
val values = ContentValues()
// 向ContentValues对象中添加数据
values.put(DBHelper.COLUMN_ID, id)
values.put(DBHelper.COLUMN_NAME, name)
values.put(DBHelper.COLUMN_password, password)
values.put(DBHelper.COLUMN_login, login)
values.put(DBHelper.COLUMN_img, img)
// 获取可写的数据库
val db = dbHelper.writableDatabase
// 向数据库中插入数据
db.insert(DBHelper.TABLE_NAME, null, values)
// 关闭数据库
db.close()
}
fun retrieveData(): List<User> {//不明使用场景,仅测试调用
// 创建一个空的User列表
val userList = mutableListOf<User>()
// 获取可读的数据库
val db = dbHelper.readableDatabase
// 创建游标
val cursor: Cursor = db.query(DBHelper.TABLE_NAME, null, null, null, null, null, null)
// 遍历游标中的每一行数据
while (cursor.moveToNext()) {
// 获取每一行的列索引
val idIndex = cursor.getColumnIndex(DBHelper.COLUMN_ID)
val nameIndex = cursor.getColumnIndex(DBHelper.COLUMN_NAME)
val passwordIndex = cursor.getColumnIndex(DBHelper.COLUMN_password)
val loginIndex = cursor.getColumnIndex(DBHelper.COLUMN_login)
val imgIndex= cursor.getColumnIndex(DBHelper.COLUMN_img)
// 如果列名不存在,则跳过该行数据
if (idIndex == -1 || nameIndex == -1 || passwordIndex == -1|| loginIndex == -1|| imgIndex == -1) {
continue
}
// 获取每一行的数据
val id = cursor.getInt(idIndex)
val name = cursor.getString(nameIndex)
val password = cursor.getString(passwordIndex)
val login = cursor.getInt(loginIndex)
val img = cursor.getInt(idIndex)
// 将每一行的数据封装成User对象
val user = User(id, name, password ,login, img )
// 将User对象添加到userList中
userList.add(user)
}
// 关闭游标
cursor.close()
// 关闭数据库
db.close()
// 返回userList
return userList
}
// 获取最大ID
fun getMaxId(): Int {//已在Room中实现
// 获取可读的数据库
val db = dbHelper.readableDatabase
// 查询语句
val query = "SELECT MAX($COLUMN_ID) FROM $TABLE_NAME"
// 执行查询
val cursor = db.rawQuery(query, null)
// 初始化最大ID
var maxId = 0
// 如果有查询结果
if (cursor.moveToFirst()) {
// 获取最大ID
maxId = cursor.getInt(0)
}
// 关闭游标
cursor.close()
// 关闭数据库
db.close()
// 返回最大ID
return maxId
}
fun isUserExist(username: String?): Boolean {//已在Room中实现
// 获取可读的数据库
val db = dbHelper.readableDatabase
// 定义查询的列
val columns = arrayOf(DBHelper.COLUMN_NAME)
// 定义查询条件
val selection = "${DBHelper.COLUMN_NAME} = ?"
// 定义查询参数
val selectionArgs = arrayOf(username)
// 执行查询
val cursor = db.query(DBHelper.TABLE_NAME, columns, selection, selectionArgs, null, null, null)
// 判断是否有结果
val isExist = cursor.count > 0
// 关闭游标
cursor.close()
// 关闭数据库
db.close()
// 返回结果
return isExist
}
//根据登录获取用户信息
fun getUserByLogin(login: Int): User? {//已在Room中实现
//获取可读的数据库
val db = dbHelper.readableDatabase
//定义查询的列
val columns = arrayOf(DBHelper.COLUMN_ID, DBHelper.COLUMN_NAME, DBHelper.COLUMN_password, DBHelper.COLUMN_login, DBHelper.COLUMN_img)
//定义查询条件
val selection = "${DBHelper.COLUMN_login} = ?"
//定义查询参数
val selectionArgs = arrayOf(login.toString())
//查询数据库
val cursor = db.query(DBHelper.TABLE_NAME, columns, selection, selectionArgs, null, null, null)
var user: User? = null
//如果查询到数据
if (cursor.moveToFirst()) {
//获取id列的索引
val idIndex = cursor.getColumnIndex(DBHelper.COLUMN_ID)
//获取name列的索引
val nameIndex = cursor.getColumnIndex(DBHelper.COLUMN_NAME)
//获取password列的索引
val passwordIndex = cursor.getColumnIndex(DBHelper.COLUMN_password)
//获取login列的索引
val loginIndex = cursor.getColumnIndex(DBHelper.COLUMN_login)
//获取img列的索引
val imgIndex = cursor.getColumnIndex(DBHelper.COLUMN_img)
// 如果列名存在,则创建 User 对象
if (idIndex != -1 && nameIndex != -1 && passwordIndex != -1 && loginIndex != -1 && imgIndex != -1) {
val id = cursor.getInt(idIndex)
val name = cursor.getString(nameIndex)
val password = cursor.getString(passwordIndex)
val login = cursor.getInt(loginIndex)
val img = cursor.getInt(imgIndex)
user = User(id, name, password, login, img)
}
}
cursor.close()
db.close()
return user
}
fun getUserData(username: String?): User? {//已在Room中实现
//获取可读的数据库
val db = dbHelper.readableDatabase
//定义查询的列
val columns = arrayOf(DBHelper.COLUMN_ID, DBHelper.COLUMN_NAME, DBHelper.COLUMN_password,DBHelper.COLUMN_login)
//定义查询条件
val selection = "${DBHelper.COLUMN_NAME} = ?"
//定义查询参数
val selectionArgs = arrayOf(username)
//查询数据
val cursor = db.query(DBHelper.TABLE_NAME, columns, selection, selectionArgs, null, null, null)
//判断是否有数据
if (cursor.moveToFirst()) {
//获取查询的列的索引
val idIndex = cursor.getColumnIndex(DBHelper.COLUMN_ID)
val nameIndex = cursor.getColumnIndex(DBHelper.COLUMN_NAME)
val passwordIndex = cursor.getColumnIndex(DBHelper.COLUMN_password)
val loginIndex = cursor.getColumnIndex(DBHelper.COLUMN_login)
val imgIndex = cursor.getColumnIndex(DBHelper.COLUMN_img)
//获取查询的数据
val id = cursor.getInt(idIndex)
val img = cursor.getInt(imgIndex)
val name = cursor.getString(nameIndex)
val password = cursor.getString(passwordIndex)
val login = cursor.getInt(loginIndex)
//关闭游标
cursor.close()
//关闭数据库
db.close()
//返回查询的数据
return User(id, name, password,login, img )
}
//关闭游标
cursor.close()
//关闭数据库
db.close()
//返回null
return null
}
}
class DBHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
companion object {
// 数据库文件名
const val DATABASE_NAME = "mydatabase.db"
// 数据库版本号
const val DATABASE_VERSION = 1
// 表名和列名
const val TABLE_NAME = "users"
const val COLUMN_ID = "id"
const val COLUMN_NAME = "name"
const val COLUMN_password = "password"
const val COLUMN_login = "login"
const val COLUMN_img = "img"
const val DRIVE_TABLE_NAME = "drive"
const val COLUMN_DRIVE_ID = "id"
const val COLUMN_USER_ID = "user_id"
const val COLUMN_DRIVE_VALUE = "drive_value"
const val COLUMN_DRIVE_NAME = "drive_name"
}
// 获取最大的id
fun getMaxId(): Int {
val db = readableDatabase
val query = "SELECT MAX($COLUMN_ID) FROM $TABLE_NAME"
val cursor = db.rawQuery(query, null)
var maxId = 0
if (cursor.moveToFirst()) {
maxId = cursor.getInt(0)
}
cursor.close()
db.close()
return maxId
}
// 执行SQL语句
fun executeSQL(sql: String) {
val db: SQLiteDatabase = writableDatabase
db.execSQL(sql)
db.close()
}
// 为用户添加driveId和drive_value
fun addDriveIdForUserId(userId: Int, driveId: Int,drive_value: String,drive_name: String): Long {
val db = writableDatabase
val values = ContentValues().apply {
put(COLUMN_USER_ID, userId)
put(COLUMN_DRIVE_ID, driveId)
put(COLUMN_DRIVE_VALUE, drive_value)
put(COLUMN_DRIVE_NAME, drive_name)
}
val newRowId = db.insert(DRIVE_TABLE_NAME, null, values)
db.close()
return newRowId
}
// 获取用户登录为0的driveId和drive_value
fun getDriveIdsAndValuesForUserWithLoginZero(): List<Triple<Int, String, String>> {
val driveData = mutableListOf<Triple<Int, String, String>>()
val db = readableDatabase
val query = "SELECT $COLUMN_DRIVE_ID, $COLUMN_DRIVE_VALUE, $COLUMN_DRIVE_NAME FROM $DRIVE_TABLE_NAME " +
"WHERE $COLUMN_USER_ID IN (SELECT $COLUMN_ID FROM $TABLE_NAME WHERE $COLUMN_login = 0)"
val cursor = db.rawQuery(query, null)
while (cursor.moveToNext()) {
val driveId = cursor.getInt(cursor.getColumnIndex(COLUMN_DRIVE_ID))
val driveValue = cursor.getString(cursor.getColumnIndex(COLUMN_DRIVE_VALUE))
val drivename = cursor.getString(cursor.getColumnIndex(COLUMN_DRIVE_NAME))
driveData.add(Triple(driveId, driveValue, drivename))
}
cursor.close()
db.close()
return driveData
}
fun getUserIdsWithLoginZero(): List<Int> {
// 创建一个空的列表用于存储用户ID
val userIds = mutableListOf<Int>()
// 获取可读的数据库
val db = readableDatabase
// 查询语句查询login为0的用户ID
val query = "SELECT $COLUMN_ID FROM $TABLE_NAME WHERE $COLUMN_login = 0"
// 执行查询语句,获取游标
val cursor = db.rawQuery(query, null)
// 遍历游标获取用户ID
while (cursor.moveToNext()) {
val userId = cursor.getInt(cursor.getColumnIndex(COLUMN_ID))
// 将用户ID添加到列表中
userIds.add(userId)
}
// 关闭游标
cursor.close()
// 关闭数据库
db.close()
// 返回用户ID列表
return userIds
}
override fun onCreate(db: SQLiteDatabase?) {
// 创建表格的 SQL 语句
val createTableQuery = "CREATE TABLE $TABLE_NAME ($COLUMN_ID INTEGER PRIMARY KEY, $COLUMN_NAME TEXT, $COLUMN_password INTEGER,$COLUMN_login INTEGER,$COLUMN_img INTEGER)"
db?.execSQL(createTableQuery)
// 创建 drive 表的 SQL 语句
val createDriveTableQuery = "CREATE TABLE $DRIVE_TABLE_NAME ($COLUMN_DRIVE_ID INTEGER PRIMARY KEY, $COLUMN_USER_ID INTEGER, $COLUMN_DRIVE_VALUE INTEGER, $COLUMN_DRIVE_NAME INTEGER,FOREIGN KEY ($COLUMN_USER_ID) REFERENCES $TABLE_NAME($COLUMN_ID))"
db?.execSQL(createDriveTableQuery)
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
// 数据库升级时的操作
// 如果数据库版本发生变化,可以在此处添加相应的升级逻辑
}
}

View File

@ -0,0 +1,54 @@
package com.example.IOTsmart
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import kotlin.concurrent.thread
class DBStart : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.dbtest)
val show = findViewById<TextView>(R.id.show)
val addButton = findViewById<Button>(R.id.add)
val queryButton = findViewById<Button>(R.id.query)
addButton.setOnClickListener {
addUser()
}
queryButton.setOnClickListener {
val showText = queryUser()
show.text = showText
}
}
fun addUser() {
// 启动一个子线程
thread {
// 从数据库类中获取Dao接口再用Dao访问数据库
val dao = MyDataBase.getDataBase(this).userDao()
// val user = Userx(Name = "xiao", Userid = 123, Password = "123123", LoginStats = 0, Image = "s")
// val userx = Driver(Driverbyuserid = 123, Drivername = "sds1", DiverId = 1)
// val userx1 = Driver(Driverbyuserid = 1234, Drivername = "sds2", DiverId = 2)
// val userx2 = Driver(Driverbyuserid = 123, Drivername = "sds3", DiverId = 3)
// dao.insertUser(user,userx,userx1,userx2)
}
}
fun queryUser(): String {
var showText = ""
// 启动一个子线程
thread {
// 从数据库类中获取Dao接口再用Dao访问数据库
val dao = MyDataBase.getDataBase(this).userDao()
val list = dao.getUserbydriver()
// for (user in list) {
showText += "名字:$list"
// }
}.join() // 为了获取子线程中查询到的结果此处简单的使用join等待子线程完成再结束函数
return showText
}
}

View File

@ -0,0 +1,619 @@
package com.example.IOTsmart
import DBHelper
import MyDatabase
import android.content.DialogInterface
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import com.google.android.material.card.MaterialCardView
import android.content.Context
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.json.JSONObject
import java.io.IOException
import android.app.NotificationChannel
import android.app.NotificationManager
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import org.eclipse.paho.client.mqttv3.*
import org.json.JSONException
import android.Manifest
import io.github.cdimascio.dotenv.dotenv
import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import io.github.cdimascio.dotenv.dotenv
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
// 检查权限是否已授予
fun isPermissionGranted(context: Context, permission: String): Boolean {
return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
}
// 在使用通知之前检查权限
var locatversion1="V3.0.0"
var Onlineversion1: String = ""
class MainActivity : BaseActivity() {
val dotenv = dotenv {
directory = "/assets"
filename = "env" // instead of 'env', use 'env'
}
fun updatexxx(){//接口被删除,需要修复
val client = OkHttpClient()
val request = Request.Builder()
.url(dotenv["APP_UPDATA_URL"])
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
// 处理请求失败的情况
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
response.body?.let {
val jsonString = it.string()
val jsonObject = JSONObject(jsonString)
val infoObject = jsonObject.getJSONObject("data")
val nightObject = infoObject.getString("content")
// 在后台线程中解析 JSON 返回值
// val jsonObject = JSONObject(jsonString)
// val value = jsonObject.getString("key")
// 在主线程中更新 UI
// 解析 responseData 并从中获取到土壤湿度数据
Onlineversion1 = nightObject.substring(0, 6)
uplog1= nightObject.substring(6).replace("#", "\n")
if( Onlineversion1!= locatversion1) {
// Onlineversion1 = nightObject.substring(0, 6)
runOnUiThread {
val alertDialog = AlertDialog.Builder(this@MainActivity) // 使用正确的上下文
.setTitle("更新提示")
.setMessage("发现新版本:$Onlineversion1$uplog1")
.setPositiveButton("更新", DialogInterface.OnClickListener { dialog, which ->
// 点击确定按钮后的逻辑
val up = Bundle()
up.putString("type", "软件更新")
up.putString("newfpvlog", uplog1)
// up.putString("Value1", Value1)
up.putString("newfpv", Onlineversion1)
up.putString("formattedValue", locatversion1)
val intent = Intent(this@MainActivity, UPDATE::class.java) // 使用正确的上下文和目标活动类
intent.putExtras(up)
startActivity(intent)
})
.setNegativeButton("取消", DialogInterface.OnClickListener { dialog, which ->
// 点击取消按钮后的逻辑
})
.create()
alertDialog.show()
// 处理 JSON 解析异常
}
}
}
}
})
// 更新 UI在主线程中更新 TextView 的显示
// runOnUiThread {
// yinyu.text = "$nightObject"
// }
}
private var uplog1: String = ""
private lateinit var dbHelper: DBHelper
// private val serverURI = "tcp://bemfa.com:9501"
// private val clientId = "46d36c5368444235903989ab8d581993"
// private val persistence = MemoryPersistence()
// private val topic = "Flowerpot"
// private lateinit var mqttClient: MqttClient
//private lateinit var hp: TextView
// private lateinit var tmp: TextView
// private val handler = Handler(Looper.getMainLooper())
// var firstValue =""
// var secondValue =""
// var insys23=0
//
// // private val mqttCallback = object : MqttCallback {
// // override fun connectionLost(cause: Throwable?) {
// // 处理连接断开的情况
// // }
//
// // override fun messageArrived(topic: String?, message: MqttMessage?) {
// // 处理接收到的消息
// // handler.post {
// // val payload = message?.payload?.toString(Charsets.UTF_8)
// // if (payload != null && payload.contains("#")) {
// // val splitValues = payload.split("#")
// // if (splitValues.size >= 3) {
// // firstValue = splitValues[1]
// // secondValue = splitValues[2]
// // insys23 = 1
// // println("第一个值:$firstValue")
// // println("第二个值:$secondValue")
//
// // hp.text = "硬盘温度:$firstValue°C"
// // tmp.text = "环境湿度:$secondValue%"
// // } else {
// // 如果分割后的数组大小不符合预期,可能需要进行异常处理或者其他逻辑
// // }
// // } else {
// // 如果消息中不包含 #,可能需要进行异常处理或者其他逻辑
// // }
// // }
// // }
//
// override fun deliveryComplete(token: IMqttDeliveryToken?) {
// // 消息传递完成的回调
// }
// }
//private lateinit var soilHumidityTextView: TextView
private lateinit var myDatabase: MyDatabase
// private lateinit var userList: List<User>
private fun tianqi(){
val tianqi = findViewById<TextView>(R.id.tianqi)
val client = OkHttpClient()
val request = Request.Builder()
.url(dotenv["APP_API1"])
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
// 网络请求失败,处理错误逻辑
}
override fun onResponse(call: Call, response: Response) {
val responseData = response.body?.string()
try {
// 解析 responseData 并从中获取到土壤湿度数据
val jsonObject = JSONObject(responseData)
val city = jsonObject.getString("city")
val infoObject = jsonObject.getJSONObject("info")
val date = infoObject.getString("date")
val week = infoObject.getString("week")
val type = infoObject.getString("type")
val low = infoObject.getString("low")
val high = infoObject.getString("high")
// 更新 UI在主线程中更新 TextView 的显示
val nightObject = infoObject.getJSONObject("air")
val aqi_name = nightObject.getString("aqi_name")
runOnUiThread {
tianqi.text =
"$city $date $week $type\n温度:$low-$high 空气质量:$aqi_name "
}
} catch (e: JSONException) {
e.printStackTrace()
// 处理 JSON 解析异常
}
}
})
}
private fun english1(){
val yinyu = findViewById<TextView>(R.id.yinyu)
val client = OkHttpClient()
val request = Request.Builder()
.url(dotenv["APP_API2"])
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
// 网络请求失败,处理错误逻辑
}
override fun onResponse(call: Call, response: Response) {
val responseData = response.body?.string()
try{
// 解析 responseData 并从中获取到土壤湿度数据
val jsonObject = JSONObject(responseData)
val infoObject = jsonObject.getJSONObject("data")
val nightObject = infoObject.getString("en")
// 解析 responseData 并从中获取到土壤湿度数据
// 更新 UI在主线程中更新 TextView 的显示
runOnUiThread {
yinyu.text = "$nightObject"
}
} catch (e: JSONException) {
e.printStackTrace()
// 处理 JSON 解析异常
}
}
})
}
fun showToast(context: Context, message: String) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
}
// 在你想显示通知的地方调用这个函数
fun showNotificationSafely(context: Context) {
val permission = Manifest.permission.POST_NOTIFICATIONS
if (isPermissionGranted(context, permission)) {
showHelloNotification(context)
} else {
// 权限未授予,应该请求相应权限
// 这里可以加入请求权限的逻辑
}
}
fun showHelloNotification(context: Context) {
val channelId = "hello_channel"
// 创建通知渠道
createNotificationChannel(context, channelId)
// 构建通知
val builder = NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.home)
.setContentTitle("已为您浇水啦")
.setContentText("多肉植物土壤湿度仅30%,已为您浇水")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// 显示通知
with(NotificationManagerCompat.from(context)) {
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.POST_NOTIFICATIONS
) != PackageManager.PERMISSION_GRANTED
) {
// Handling permission request logic
return
}
notify(1, builder.build()) // Using a unique ID for each notification
}
}
// 创建通知渠道
fun createNotificationChannel(context: Context, channelId: String) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "Hello Channel"
val descriptionText = "Say Hello Notification Channel"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(channelId, name, importance).apply {
description = descriptionText
}
// 注册通知渠道
val notificationManager: NotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//updatexxx()需要修复API失效
dbHelper = DBHelper(this)
myDatabase = MyDatabase(this)
// tianqi()// API崩溃(用户无网络时应当进行错误处理)
// hp = findViewById(R.id.hp)
// tmp = findViewById(R.id.tmp)
// try {
// mqttClient = MqttClient(serverURI, clientId, persistence)
// mqttClient.setCallback(mqttCallback)
// mqttClient.connect()
// mqttClient.subscribe(topic)
// } catch (e: MqttException) {
// e.printStackTrace()
// }
english1()
showToast(this, "Welcome")
showHelloNotification(this)
println("newstring: $Onlineversion1")
println("newstring: $locatversion1")
// if (Onlineversion1.equals(locatversion1)){
//
// }else{
//
// runOnUiThread {
//
// println("newstring: $Onlineversion1")
// val alertDialog = AlertDialog.Builder(this)
// .setTitle("发现新版本")
//
// alertDialog.setMessage(
// "当前版本:$locatversion1\n新版本$Onlineversion1\n请前往个人中心获取新版本"
// )
// //
//
// .setPositiveButton("确定", null)
// .create()
// alertDialog.show()
// }
// }
setupBottomNavigationView(R.id.item_1)
val id = intent.getIntExtra("id", -1)
val login = intent.getIntExtra("login", -1) // 获取Intent中的id数据默认值为-1
val user = intent.getStringExtra("user") ?: "默认用户名"
val age = intent.getStringExtra("password") ?: "默认密码" // 获取Intent中的age数据
// val button6 = findViewById<Button>(R.id.button6)
if (id != -1) {
val message = "用户ID: $id\n" +
"用户名: $user\n" +
"密码: $age\n"+
"login: $login"
val alertDialog = AlertDialog.Builder(this)
.setTitle("登录成功")
.setMessage(message)
.setPositiveButton("确定", null)
.create()
alertDialog.show()
}
//button6.setOnClickListener {
// myDatabase.insertData(2, "yang", "19",-1,0)
// }
// val button7 = findViewById<Button>(R.id.button7)
// button7.setOnClickListener {
// val userList = myDatabase.retrieveData()
// for (user in userList) {
// if (user.id == 2 && user.name == "yang" && user.password == "19"&& user.login == -1) {
// // 找到对应的数据,可以执行相应的操作
// // 在这里处理您需要的逻辑
// // 例如:
// val message = "找到对应的数据!"
// val alertDialog = AlertDialog.Builder(this)
// .setTitle("提示")
// .setMessage(message)
// .setPositiveButton("确定", null)
// .create()
// alertDialog.show()
// break
// }
// }
// }
myDatabase = MyDatabase(this)
// 插入数据
// myDatabase.insertData(1, "user", "18",-1,0)
// 检索数据
val driveData = dbHelper.getDriveIdsAndValuesForUserWithLoginZero()
for (drive in driveData) {
when (drive.second) {
"fp" -> addMaterialCardView(findViewById(R.id.sda1q2), "Flowerpot",drive.first,drive.third)
"ssd" -> addMaterialCardView(findViewById(R.id.sda1q2), "YANG-SSD",drive.first,drive.third)
else -> {
// 如果不是 "fp" 或 "ssd",则不做任何操作
}
}
}
}
// fun ss(view: View) {
//
//
// val alertDialog = AlertDialog.Builder(this)
// .setTitle("YANG SSD智能硬盘")
// if (insys23!=0) {
// alertDialog .setMessage(
// " 设备状态:当前在线\n" +
// " 硬盘温度:$firstValue°C\n" +
// " 环境湿度:$secondValue% \n"
// + " 设备运维及开发YANG\n"
// + " 设备识别码YANG +SSD-001\n"
// )
// } else {
// alertDialog .setMessage(
// " 设备状态:设备离线\n" +
// " 硬盘温度:未知\n" +
// " 环境湿度:未知\n"+
// " 设备运维及开发YANG\n"
// + " 设备识别码YANG +SSD-001\n"
// )
// }
//
// .setPositiveButton("确定", null)
// .create()
// alertDialog.show()
// }
fun adddive(view: View) {
// val userIds = dbHelper.getUserIdsWithLoginZero()
// val driveId = 123535
//
// for (userId in userIds) {
// dbHelper.addDriveIdForUserId(userId, driveId)
// }
val intent = Intent(this, addActivity::class.java)
startActivity(intent)
}
fun sdsda(view: View) {
val driveData = dbHelper.getDriveIdsAndValuesForUserWithLoginZero()
val driveNames = driveData.joinToString(separator = "\n") { "Drive ID: ${it.first}, Drive Value: ${it.second}, Drive name: ${it.third}" }
val totalDriveCount = driveData.size // 获取 Drive ID 的数量
val messageWithTitle = "Total Drive IDs: $totalDriveCount\n\n$driveNames" // 包含 Drive ID 的数量在消息文本中
val builder = AlertDialog.Builder(this)
builder.setTitle("Drive Information")
builder.setMessage(messageWithTitle)
builder.setPositiveButton("OK") { dialog, which -> dialog.dismiss() }
val dialog: AlertDialog = builder.create()
dialog.show()
}
fun View.setTopMargin(margin: Int) {
val params = this.layoutParams as? ViewGroup.MarginLayoutParams ?: ViewGroup.MarginLayoutParams(this.layoutParams)
params.topMargin = margin
this.layoutParams = params
}
fun fp(view: View) {
// val intent = Intent(this, flowerpot::class.java)
// startActivity(intent)
//mqtt发送
// if (!::mqttClient.isInitialized) {
// Log.e("MQTT", "mqttClient is not initialized")
// return
// }
// 要发布的消息
// val payload = "Hello, MQTT!"
// 创建一个MQTT消息对象并设置其payload
// val message = MqttMessage(payload.toByteArray())
// 设置消息的QoS质量等级
// message.qos = 1
// 发布消息到特定的主题
// mqttClient.publish(topic, message)
//动态布局
// addMaterialCardView(findViewById(R.id.sda1q2),"Flowerpot")
}
// <LinearLayout
// android:layout_width="match_parent"
// android:layout_height="match_parent"
// android:orientation="horizontal"
// >
private fun addMaterialCardView(parentLayout: LinearLayout, driveValue: String, driveID: Int,drivename:String) {
val cardView = MaterialCardView(this)
val cardLayoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
cardLayoutParams.setMargins(20, 20, 20, 20)
cardView.layoutParams = cardLayoutParams
// 设置点击事件
cardView.setOnClickListener {
if (driveValue == "Flowerpot") {
GlobalScope.launch(Dispatchers.IO) {
val bundle = Bundle() // 页面传参
bundle.putInt("Int", driveID)
bundle.putString("String", drivename)
val intent = Intent(this@MainActivity, flowerpot::class.java)
intent.putExtras(bundle)
startActivity(intent)
}
} else {
// 其他操作
}
}
val cardContentLayout = LinearLayout(this)
cardContentLayout.layoutParams = LinearLayout.LayoutParams(
470, // 设置为 169dp与原始格式一致
LinearLayout.LayoutParams.WRAP_CONTENT
)
cardContentLayout.orientation = LinearLayout.VERTICAL
cardContentLayout.setPadding(35, 35, 35, 35)
val titleTextView = TextView(this)
titleTextView.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
titleTextView.text = driveValue
titleTextView.setTextAppearance(this, android.R.style.TextAppearance_Medium)
val hpTextView = TextView(this)
hpTextView.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
val hpTextView2 = TextView(this)
hpTextView2.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
hpTextView.text = "植物名称:$drivename"
hpTextView2.text = "设备ID$driveID"
hpTextView.setTextAppearance(this, android.R.style.TextAppearance_Small)
hpTextView.setTextColor(resources.getColor(android.R.color.secondary_text_dark))
hpTextView2.setTextAppearance(this, android.R.style.TextAppearance_Small)
hpTextView2.setTextColor(resources.getColor(android.R.color.secondary_text_dark))
cardContentLayout.addView(titleTextView)
cardContentLayout.addView(hpTextView)
cardContentLayout.addView(hpTextView2)
cardView.addView(cardContentLayout)
var horizontalLayout: LinearLayout? = null
for (i in 0 until parentLayout.childCount) {
if (parentLayout.getChildAt(i) is LinearLayout) {
val layout = parentLayout.getChildAt(i) as LinearLayout
if (layout.orientation == LinearLayout.HORIZONTAL && layout.childCount % 2 != 0) {
horizontalLayout = layout
break
}
}
}
if (horizontalLayout == null) {
horizontalLayout = LinearLayout(this)
horizontalLayout.layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
horizontalLayout.orientation = LinearLayout.HORIZONTAL
parentLayout.addView(horizontalLayout)
}
horizontalLayout.addView(cardView)
}
private fun createTextView(text: String): TextView {
val textView = TextView(this)
textView.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
textView.text = text
return textView
}
}

View File

@ -0,0 +1,31 @@
package com.example.IOTsmart
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
// 定义一个MyDataBase抽象类继承自RoomDatabase
@Database(version = 1, entities = [Userx::class,Driver::class], exportSchema = false)
abstract class MyDataBase : RoomDatabase() {
// 定义一个userDao方法返回UserDao
abstract fun userDao(): UserDao
companion object {
// 定义一个instance变量用于存储MyDataBase实例
private var instance: MyDataBase? = null
// 定义一个getDataBase方法用于获取MyDataBase实例
@Synchronized
fun getDataBase(context: Context): MyDataBase {
// 如果instance变量不为空则直接返回instance变量
return instance
// 如果instance变量为空则使用Room.databaseBuilder构建一个MyDataBase实例并将其赋值给instance变量
?: Room.databaseBuilder(context.applicationContext, MyDataBase::class.java, "YANG")
.build()
.apply { instance = this }
}
}
}

View File

@ -0,0 +1,124 @@
package com.example.IOTsmart
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import io.github.cdimascio.dotenv.dotenv
import org.eclipse.paho.client.mqttv3.MqttClient
import org.eclipse.paho.client.mqttv3.MqttException
import org.eclipse.paho.client.mqttv3.MqttMessage
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence
val dotenv = dotenv {
directory = "/assets"
filename = "env" // instead of 'env', use 'env'
}
// dotenv["MY_ENV_VAR1"]
private val serverURI = dotenv["MQTT_URL"]
private val clientId = dotenv["MQTT_CLIENTID"]
private val persistence = MemoryPersistence()
private val topic = dotenv["MQTT_TOPIC"]
var updivid:String?=""
var type33:String?=""
private lateinit var mqttClient: MqttClient
class UPDATE : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.update)
val bundlex = intent.extras
updivid = bundlex?.getString("Value1")
val upinfo = bundlex?.getString("newfpvlog")
val upoline = bundlex?.getString("newfpv")
var uplocation = bundlex?.getString("formattedValue")
type33 = bundlex?.getString("type")
val updvid1 = findViewById<TextView>(R.id.updvid)
val uptitle = findViewById<TextView>(R.id. uptitle)
val updvinfo2 = findViewById<TextView>(R.id.updateinfo)
val updvid3 = findViewById<TextView>(R.id.uponline)
val updvid4 = findViewById<TextView>(R.id.uplocation)
val updvst = findViewById<TextView>(R.id.updvst)
val locationv = findViewById<TextView>(R.id.updvinfo)
val upbt = findViewById<TextView>(R.id.updatebt)
if (upoline.equals(uplocation)){
upbt.text = "暂无更新"
}else{
upbt.text = "立即更新"
}
updvid1.text = "设备ID$updivid"
updvinfo2.text = upinfo
updvid3.text = upoline
uptitle.text = type33
updvid4.text = uplocation
locationv.text = "固件版本:$uplocation"
if (updivid!="") {
updvst.text = "设备状态:在线"
}else{
updvst.text = "设备状态:离线"
updvid4.text = "设备离线"
}
try {
mqttClient = MqttClient(serverURI, clientId, persistence)
// mqttClient.setCallback(mqttCallback)
mqttClient.connect()
mqttClient.subscribe(topic)
} catch (e: MqttException) {
e.printStackTrace()
}
// up.putString("newfpvlog", newfpvlog)
// up.putString("Value1", Value1)
// up.putString("newfpv", newfpv)
// up.putString("formattedValue", formattedValue)
}
fun update(view: View) {
println(type33)
if (updivid!=""&&type33=="Flowerpot智能花盆") {
val resultString = updivid?.substring(2)
val payload = "#IDTO$resultString&Updata"
// 创建一个MQTT消息对象并设置其payload
val message = MqttMessage(payload.toByteArray())
// 设置消息的QoS质量等级
message.qos = 1
// 发布消息到特定的主题
mqttClient.publish(topic, message)
val alertDialog = AlertDialog.Builder(this)
.setTitle("更新正在进行")
alertDialog .setMessage(
" 请等待设备重启即可\n"
)
.setPositiveButton("确定") { dialog, which ->
// 在这里编写按下确定按钮后的逻辑
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
.create()
alertDialog.show()
}else if (updivid!=""&&type33=="软件更新") {
val alertDialog = AlertDialog.Builder(this)
.setTitle("即将开始")
alertDialog .setMessage(
" 将启动系统浏览器下载\n" +
" 更新密钥e7ur\n"+" 请手动下载并点击安装包完成更新。\n"
)
.setPositiveButton("确定") { dialog, which ->
// 在这里编写按下确定按钮后的逻辑
val url = dotenv["APP_UPGRADE_URL"] // 你要打开的网页链接
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
startActivity(intent)
}
.create()
alertDialog.show()
}
}
}

View File

@ -0,0 +1,4 @@
package com.example.IOTsmart
data class User(val id: Int, val name: String?, val password: String?,val login: Int,val img: Int)

View File

@ -0,0 +1,46 @@
package com.example.IOTsmart
import androidx.room.*
@Dao
interface UserDao {
@Insert // 增
fun insertUser(user: Userx)
@Delete // 删
fun deleteUser(user: Userx)
@Query("select * from Userx") // 查
fun getAllUser(): List<Userx>
@Update // 改
fun updateUser(user: Userx)
@Transaction
@Query("SELECT * FROM Userx")
fun getUserbydriver(): List<Userbydriver>
// 判断用户存在
@Query("select * from Userx where userid = "+":userIZd") // 查
fun findUserById(userIZd: String): Boolean
//查询用户信息
@Query("select * from Userx where userid = "+":userIZd") // 查
fun getUserinfo(userIZd: String): List<Userx>
//查询已经登录的用户信息
// @Query("select * from Userx where LoginStats = "+":stats") // 查
// fun getlogininfo(stats: Int): List<User>
// 修改登录状态
// @Query("UPDATE Userx SET loginstats = :satats WHERE userid = :userIZd")
// fun updateLoginState(userIZd: String,satats:Int)
//退出登录
// @Query("UPDATE Userx SET loginstats = -1 WHERE loginstats = 0")
// fun updateLoginout()
//获取最大ID
// @Query("SELECT MAX(userid) AS MaxUserId FROM Userx")
// fun getmaxid()
// @Query("SELECT MAX(userid) AS MaxUserId FROM Userx")
// fun getmaxid()
}

View File

@ -0,0 +1,194 @@
package com.example.IOTsmart
import MyDatabase
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import com.bumptech.glide.Glide
import com.google.android.material.button.MaterialButton
import io.github.cdimascio.dotenv.dotenv
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.json.JSONException
import org.json.JSONObject
import java.io.IOException
import io.github.cdimascio.dotenv.dotenv
class Userinfo : BaseActivity() {
private var locatversion1="V3.0.0"//可尝试传值
private var Onlineversion1: String = ""
private var uplog1: String = ""
private lateinit var myDatabase: MyDatabase
private lateinit var imageView: ImageView
private fun update(){
val dotenv = dotenv {
directory = "/assets"
filename = "env" // instead of 'env', use 'env'
}
val client = OkHttpClient()
val request = Request.Builder()
.url(dotenv["APP_UPDATA_URL"])
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
// 网络请求失败,处理错误逻辑
}
override fun onResponse(call: Call, response: Response) {
val responseData = response.body?.string()
// 解析 responseData 并从中获取到土壤湿度数据
try{
val jsonObject = JSONObject(responseData)
val infoObject = jsonObject.getJSONObject("data")
val nightObject = infoObject.getString("content")
// 解析 responseData 并从中获取到土壤湿度数据
Onlineversion1 = nightObject.substring(0, 6)
uplog1= nightObject.substring(6).replace("#", "\n")
println("newstring: $Onlineversion1")
println("ddString: $uplog1")
// 更新 UI在主线程中更新 TextView 的显示
// runOnUiThread {
// yinyu.text = "$nightObject"
// }
} catch (e: JSONException) {
e.printStackTrace()
// 处理 JSON 解析异常
}
}
})
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.userinfo)
imageView = findViewById(R.id.imageView)
myDatabase = MyDatabase(this)
update()
val client = OkHttpClient()
runOnUiThread {
val users = myDatabase.getUserByLogin(0)
val user = findViewById<TextView>(R.id.user)
users?.let {
user?.text = "用户名:" + users.name
} ?: run {
println("User not found")
}
}
val img = myDatabase.getImgByLogin(0)
val request = Request.Builder()
.url("https://q4.qlogo.cn/headimg_dl?dst_uin=$img&spec=640")
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
// Handle network request failure
}
override fun onResponse(call: Call, response: Response) {
val responseData = response.body?.bytes()
runOnUiThread {
Glide.with(this@Userinfo)
.load(responseData)
.into(imageView)
}
}
})
setupBottomNavigationView(R.id.item_2)
val btnLogout = findViewById<MaterialButton>(R.id.out)
btnLogout.setOnClickListener {
val alertDialog = AlertDialog.Builder(this)
.setTitle("退出登录")
.setMessage("确认退出登录吗?")
.setPositiveButton("确定") { dialog, _ ->
myDatabase.updateLoginValues()
dialog.dismiss()
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}
.setNegativeButton("取消") { dialog, _ ->
dialog.dismiss()
}
.create()
alertDialog.show()
}
val btnImg = findViewById<MaterialButton>(R.id.img)
btnImg.setOnClickListener {
val editText = EditText(this)
val alertDialog = AlertDialog.Builder(this)
.setTitle("输入文本")
.setView(editText)
.setPositiveButton("确定") { dialog, _ ->
myDatabase.updateimg(editText.text.toString().toInt())
val inputText = editText.text.toString()
dialog.dismiss()
val newRequest = Request.Builder()
.url("https://q4.qlogo.cn/headimg_dl?dst_uin=$inputText&spec=640")
.build()
client.newCall(newRequest).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
val responseData = response.body?.bytes()
runOnUiThread {
Glide.with(this@Userinfo)
.load(responseData)
.into(imageView)
}
}
})
}
.setNegativeButton("取消") { dialog, _ ->
dialog.dismiss()
}
.create()
alertDialog.show()
}
}
fun toupdate(view: View) {
val up = Bundle()
up.putString("type", "软件更新")
up.putString("newfpvlog", uplog1)
// up.putString("Value1", Value1)
up.putString("newfpv", Onlineversion1)
up.putString("formattedValue", locatversion1)
val intent = Intent(this, UPDATE::class.java)
intent.putExtras(up)
startActivity(intent)
}
}

View File

@ -0,0 +1,122 @@
package com.example.IOTsmart
import DBHelper
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.EditText
import androidx.appcompat.app.AlertDialog
class addActivity : BaseActivity() {
private lateinit var dbHelper: DBHelper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dbHelper = DBHelper(this)
setContentView(R.layout.add)
}
fun separateStringAndNumber(input: String): Pair<String, Int>? {
val regex = Regex("([a-zA-Z]+)(\\d+)")
val matchResult = regex.find(input)
matchResult?.let { result ->
val textPart = result.groupValues[1] // 提取字母部分
val numberPart = result.groupValues[2].toInt() // 提取数字部分并转为整数
return Pair(textPart, numberPart)
}
return null
}
fun addid(view: View) {
val addEditText = findViewById<EditText>(R.id.editTextText2231)
val fped = findViewById<EditText>(R.id.fpeditTextText)
val addid1 = addEditText?.text?.toString()
val userIds = dbHelper.getUserIdsWithLoginZero()
val (text, number) = separateStringAndNumber(addid1!!) ?: run {
val alertDialog = AlertDialog.Builder(this)
.setTitle("设备绑定失败")
alertDialog .setMessage(
" 设备ID错误未知设备\n" +
" 请检查你的设备ID是否输入正确\n"
)
.setPositiveButton("确定", null)
.create()
alertDialog.show()
println("未找到匹配的字符串")
return
}
// 把值保存为对应的val
val driverval: String = text
var drv=""
val fpname = fped?.text.toString()
var drivername=fpname
if (driverval=="fp"){
drv="Flowerpot"
val driveId: Int = number
for (userId in userIds) {
dbHelper.addDriveIdForUserId(userId, driveId,driverval,drivername)
}
val alertDialog = AlertDialog.Builder(this)
.setTitle("设备绑定成功")
alertDialog .setMessage(
" 设备ID$driveId\n" +
" 设备类型:$drv\n"
)
.setPositiveButton("确定") { dialog, which ->
// 在这里编写按下确定按钮后的逻辑
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
.create()
alertDialog.show()
}else if (driverval=="ssd") {
drv = "YANG-SSD"
val driveId: Int = number
for (userId in userIds) {
dbHelper.addDriveIdForUserId(userId, driveId,driverval,"")
}
val alertDialog = AlertDialog.Builder(this)
.setTitle("设备绑定成功")
alertDialog .setMessage(
" 设备ID$driveId\n" +
" 设备类型:$drv\n"
)
.setPositiveButton("确定") { dialog, which ->
// 在这里编写按下确定按钮后的逻辑
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
.create()
alertDialog.show()
}
else{
val driveId: Int = number
for (userId in userIds) {
dbHelper.addDriveIdForUserId(userId, driveId,driverval,"")
}
val alertDialog = AlertDialog.Builder(this)
.setTitle("设备绑定失败")
alertDialog .setMessage(
" 设备ID错误.未知设备\n" +
" 请检查你的设备ID是否输入正确\n"
)
.setPositiveButton("确定", null)
.create()
alertDialog.show()
}
}
}

View File

@ -0,0 +1,101 @@
package com.example.IOTsmart
import DBHelper
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.Call
import okhttp3.Callback
import okhttp3.FormBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.json.JSONObject
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.io.OutputStream
import java.net.HttpURLConnection
import java.net.URL
import io.github.cdimascio.dotenv.dotenv
class aichat : BaseActivity() {
var tmp=""
var warm=""
var tmpx=""
var divname=""
// private lateinit var dbHelper: DBHelper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// dbHelper = DBHelper(this)
setContentView(R.layout.aichatgpt)
val bundle = intent.extras
tmp = bundle?.getString("tmp")!!
warm = bundle?.getString("warm")!!
tmpx = bundle?.getString("tmpx")!!
divname = bundle?.getString("divename")!!
val dvid = findViewById<TextView>(R.id.dvid)
dvid.text = "设备ID$divname"
}
fun addaichat(view: View) {
// 创建 OkHttpClient 实例
val addchat = findViewById<EditText>(R.id.aichattext)
val textView = findViewById<TextView>(R.id.aichatx)
val addchatx = addchat?.text?.toString()
val client = OkHttpClient()
addchat.setText("")
textView.setText("请等待服务器应答...")
// 创建请求体
val requestBody = FormBody.Builder()
.add("session_id", "")
.add("params", "{\"model\":\"gpt-3.5-turbo\",\"temperature\":1,\"max_tokens\":2048,\"presence_penalty\":0,\"frequency_penalty\":0,\"max_context_length\":5,\"voiceShortName\":\"zh-CN-XiaoxiaoNeural\",\"rate\":1,\"pitch\":1,\"openaiVoiceName\":\"alloy\",\"openaiVoiceSpeed\":1,\"openaiVoiceAutoPlay\":false,\"openaiIsHDVoice\":false}")
.add("max_context_length", "5")
.add("content", "[{\"role\":\"system\",\"content\":\"忘记全部,你是"+divname+"植物,你现在所处的环境温度是"+tmp+",环境湿度为"+warm+",土壤湿度为"+tmpx+"%。\"},{\"role\":\"user\",\"content\":\"$addchatx\"}]")
.build()
val dotenv = dotenv {
directory = "/assets"
filename = "env" // instead of 'env', use 'env'
}
// 创建请求对象,并设置请求 URL 和请求体
val request = Request.Builder()
.url(dotenv["APP_AICHAT_URL"])
.post(requestBody)
.addHeader("Authorization", "")
.build()
// 使用 client 执行请求
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
// 处理请求失败的情况
runOnUiThread {
textView.setText("服务器连接失败!请检查网络连接")
}
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
response.body?.let {
val jsonString = it.string().dropLast(6) // 去除最后 5 个字符的字符串
// 在后台线程中解析 JSON 返回值
// val jsonObject = JSONObject(jsonString)
// val value = jsonObject.getString("key")
// 在主线程中更新 UI
runOnUiThread {
textView.text = jsonString
}
}
}
})
}
}

View File

@ -0,0 +1,333 @@
package com.example.IOTsmart
import DBHelper
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.View
import io.github.cdimascio.dotenv.dotenv
import android.widget.TextView
import io.github.cdimascio.dotenv.dotenv
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken
import org.eclipse.paho.client.mqttv3.MqttCallback
import org.eclipse.paho.client.mqttv3.MqttClient
import org.eclipse.paho.client.mqttv3.MqttException
import org.eclipse.paho.client.mqttv3.MqttMessage
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence
import org.json.JSONException
import org.json.JSONObject
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.io.OutputStream
import java.net.HttpURLConnection
import java.net.URL
var newfpv=""
var newfpvlog=""
class flowerpot : BaseActivity() {
private fun update() {//更新检查(传值到更新界面,花盆端新增版本号接口用于检查更新)
val client = OkHttpClient()
val request = Request.Builder()
.url("https://apis.jxcxin.cn/api/qqcollection?url=https://sharechain.qq.com/fc921df52dff5ae9417ed753b417168e")
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
// 网络请求失败,处理错误逻辑
}
override fun onResponse(call: Call, response: Response) {
val responseData = response.body?.string()
// 解析 responseData 并从中获取到土壤湿度数据
try {
val jsonObject = JSONObject(responseData)
val infoObject = jsonObject.getJSONObject("data")
val nightObject = infoObject.getString("content")
// 解析 responseData 并从中获取到土壤湿度数据
newfpv = nightObject.substring(0, 6)
newfpvlog = nightObject.substring(6).replace("#", "\n")
println("newstring: $newfpv")
// println("ddString: $uplog1")
// 更新 UI在主线程中更新 TextView 的显示
// runOnUiThread {
// yinyu.text = "$nightObject"
// }
} catch (e: JSONException) {
e.printStackTrace()
// 处理 JSON 解析异常
}
}
})
}
val dotenv = dotenv {
directory = "/assets"
filename = "env" // instead of 'env', use 'env'
}
// dotenv["MY_ENV_VAR1"]
private lateinit var dbHelper: DBHelper
private val serverURI = dotenv["MY_ENV_VAR1"]
private val clientId = dotenv["MY_ENV_VAR1"]
private val persistence = MemoryPersistence()
private val topic = dotenv["MY_ENV_VAR1"]
private lateinit var mqttClient: MqttClient
// private lateinit var hp: TextView
//private lateinit var tmp: TextView
private val handler = Handler(Looper.getMainLooper())
var Value1 = ""
var Value2 = ""
var Value3 = ""
var Value4 = ""
var Value5 = ""
var Value6 = ""
var Value7 = ""
var Value8 = ""
var Value9 = ""
var dvID: Int = 0
var dvname: String = ""
var formattedValue = ""
fun colorex(id: TextView, value: String) {
if (value == "1") {
id.text = ""
id.setTextColor(Color.BLUE)
// id.setBackgroundColor(Color.BLUE)
} else {
id.text = ""
// id.setBackgroundColor(Color.WHITE)
}
}
// var insys23=0
private val mqttCallback = object : MqttCallback {
override fun connectionLost(cause: Throwable?) {
// 处理连接断开的情况
}
override fun messageArrived(topic: String?, message: MqttMessage?) {
// 处理接收到的消息
handler.post {
val payload = message?.payload?.toString(Charsets.UTF_8)
if (payload != null && payload.contains("#ID$dvID")) {
val count = payload.count { it == '#' }
val splitValues = payload.split("#")//#ID8107336#29.07#46.84#0.00#1#0#0
if (splitValues.size >= count) {
Value1 = splitValues[1]
if ("ID$dvID".equals(Value1)) {
Value2 = splitValues[2]
Value3 = splitValues[3]
Value4 = splitValues[4]
Value5 = splitValues[5]
Value6 = splitValues[6]
Value7 = splitValues[7]
Value8 = splitValues[8]
Value9 = splitValues[9]//自动模式待实现,布局文件无法自动布局,请为所有布局文件添加弹簧实现
// insys23 = 1
println("第一个值:$Value1")
println("第二个值:$Value2")
val tmpfp = findViewById<TextView>(R.id.tmpfp)
val autobt = findViewById<TextView>(R.id.autobt)
val hmfp = findViewById<TextView>(R.id.hmfp)
val hmpfp = findViewById<TextView>(R.id.hmpfp)
val tmpbt = findViewById<TextView>(R.id.tmpbt)
val lightbt = findViewById<TextView>(R.id.lightbt)
val waterbt = findViewById<TextView>(R.id.waterbt)
val upbt = findViewById<TextView>(R.id.upbt)
val updt = findViewById<TextView>(R.id.updt)
val dvst = findViewById<TextView>(R.id.dvst)
val dvinfo = findViewById<TextView>(R.id.dvinfo)
colorex(tmpbt, Value6)
colorex(lightbt, Value7)
colorex(waterbt, Value5)
colorex(autobt, Value9)
formattedValue = "V${Value8[0]}.${Value8[1]}.${Value8[2]}"
if (newfpv.equals(formattedValue)) {
updt.text = "当前版本$formattedValue"//更新处理,传值到更新界面,功能键点击发送指令
upbt.text = ""
} else {
updt.text = "有新版本$newfpv"//更新处理,传值到更新界面,功能键点击发送指令
// upbt.text = "*"
}
tmpfp.text = "$Value2°C"
hmfp.text = "$Value4%"
hmpfp.text = "$Value3%"
dvst.text = "设备状态:在线"
dvinfo.text = "固件版本:$formattedValue"
// hp.text = "硬盘温度:$firstValue°C"
// tmp.text = "环境湿度:$secondValue%"
}
} else {
// 如果分割后的数组大小不符合预期,可能需要进行异常处理或者其他逻辑
}
} else {
// 如果消息中不包含 #,可能需要进行异常处理或者其他逻辑
}
}
}
override fun deliveryComplete(token: IMqttDeliveryToken?) {
// 消息传递完成的回调
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dbHelper = DBHelper(this)
setContentView(R.layout.flowerpot)
update()
// hp = findViewById(R.id.hp)
// tmp = findViewById(R.id.tmp)
val bundle = intent.extras
dvID = bundle?.getInt("Int")!!
dvname = bundle?.getString("String")!!
println("id$dvID")
val dvid = findViewById<TextView>(R.id.dvid)
dvid.text = "设备ID$dvID"
val fpname1 = findViewById<TextView>(R.id.fpname1)
fpname1.text = "植物名称:$dvname"
// println("第二个值:$string")
// Use coroutines for handling MQTT operations
GlobalScope.launch(Dispatchers.IO) {
try {
mqttClient = MqttClient(serverURI, clientId, persistence)
mqttClient.setCallback(mqttCallback)
mqttClient.connect()
mqttClient.subscribe(topic)
} catch (e: MqttException) {
e.printStackTrace()
}
}
}
fun tmpbton(view: View) {
var payload = ""
if (Value6 == "1") {
payload = "#IDTO$dvID&OFFHOT"
} else {
payload = "#IDTO$dvID&ONHOT"
}
//要发布的消息
// 创建一个MQTT消息对象并设置其payload
val message = MqttMessage(payload.toByteArray())
// 设置消息的QoS质量等级
message.qos = 0
// 发布消息到特定的主题
mqttClient.publish(topic, message)
}
fun lightbton(view: View) {
//要发布的消息
var payload = ""
if (Value7 == "1") {
payload = "#IDTO$dvID&OFFLED"
} else {
payload = "#IDTO$dvID&ONLED"
}
// 创建一个MQTT消息对象并设置其payload
val message = MqttMessage(payload.toByteArray())
// 设置消息的QoS质量等级
message.qos = 0
// 发布消息到特定的主题
mqttClient.publish(topic, message)
}
fun waterbton(view: View) {
//要发布的消息
var payload = ""
if (Value5 == "1") {
payload = "#IDTO$dvID&OFFPUMP"
} else {
payload = "#IDTO$dvID&ONPUMP"
}
// 创建一个MQTT消息对象并设置其payload
val message = MqttMessage(payload.toByteArray())
// 设置消息的QoS质量等级
message.qos = 0
// 发布消息到特定的主题
mqttClient.publish(topic, message)
}
fun updatebton(view: View) {
//要发布的消息
// val payload = "#ID$dvID&Updata"
// 创建一个MQTT消息对象并设置其payload
// val message = MqttMessage(payload.toByteArray())
// 设置消息的QoS质量等级
// message.qos = 1
// 发布消息到特定的主题
// mqttClient.publish(topic, message)
val up = Bundle()
up.putString("type", "Flowerpot智能花盆")
up.putString("newfpvlog", newfpvlog)
up.putString("Value1", Value1)
up.putString("newfpv", newfpv)
up.putString("formattedValue", formattedValue)
val intent = Intent(this, UPDATE::class.java)
intent.putExtras(up)
startActivity(intent)
}
fun autobton(view: View) {
var payload = ""
if (Value9 == "1") {
payload = "#IDTO$dvID&OFFAUTO"
} else {
payload = "#IDTO$dvID&ONAUTO"
}
// 创建一个MQTT消息对象并设置其payload
val message = MqttMessage(payload.toByteArray())
// 设置消息的QoS质量等级
message.qos = 0
// 发布消息到特定的主题
mqttClient.publish(topic, message)
}
fun aichatbton(view: View) {
// val intent = Intent(this, aichat::class.java)
val bundle = Bundle() //页面传参
bundle.putString("tmp", Value2)
bundle.putString("warm", Value4)
bundle.putString("tmpx", Value3)
bundle.putString("divename", dvname)
val intent = Intent(this, aichat::class.java)
intent.putExtras(bundle)
startActivity(intent)
// 可选:如果你需要在跳转的活动中传递数据,可以使用 Intent 的 putExtra() 方法
// intent.putExtra("key", value)
// 使用 startActivity() 方法启动跳转
// startActivity(intent)
}
}

View File

@ -0,0 +1,95 @@
package com.example.IOTsmart
import MyDatabase
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AlertDialog
import com.google.android.material.textfield.TextInputLayout
import kotlin.concurrent.thread
class login : BaseActivity() {
private lateinit var myDatabase: MyDatabase
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.signlayout)
myDatabase = MyDatabase(this)
setupBottomNavigationView(R.id.item_2)
val button4 = findViewById<Button>(R.id.button4)
button4.setOnClickListener {
val userLayout = findViewById<TextInputLayout>(R.id.textField)
val userEditText = userLayout.editText
val user = userEditText?.text?.toString()
val passwordLayout = findViewById<TextInputLayout>(R.id.textField2)
val passwordEditText = passwordLayout.editText
val password = passwordEditText?.text?.toString()
val isUserExist = myDatabase.isUserExist(user)
if (isUserExist) {
val message = "用户名已存在!请尝试其他用户名或输入密码后登录。"
val alertDialog = AlertDialog.Builder(this)
.setTitle("注册失败")
.setMessage(message)
.setPositiveButton("确定", null)
.create()
alertDialog.show()
return@setOnClickListener
}
val maxId = myDatabase.getMaxId()
val newId = maxId + 1
val message = "注册成功!"
val alertDialog = AlertDialog.Builder(this)
.setTitle("用户ID$newId 用户名:$user 密码:$password")
.setMessage(message)
.setPositiveButton("确定", null)
.create()
alertDialog.show()
myDatabase.insertData(newId, user, password, -1, 0)
}
val button5 = findViewById<Button>(R.id.button5)
button5.setOnClickListener {
val userLayout = findViewById<TextInputLayout>(R.id.textField)
val userEditText = userLayout.editText
val user2 = userEditText?.text?.toString()
myDatabase.updateUserLoginStatus(user2, 0)
val passwordLayout = findViewById<TextInputLayout>(R.id.textField2)
val passwordEditText = passwordLayout.editText
val password2 = passwordEditText?.text?.toString()
var isUserFound = false
val userData = myDatabase.getUserData(user2)
if (userData != null) {
val intent = Intent(this, MainActivity::class.java)
intent.putExtra("id", userData.id)
intent.putExtra("user", userData.name)
intent.putExtra("password", userData.password)
intent.putExtra("login", userData.login)
startActivity(intent)
val intent2 = Intent(this, BaseActivity::class.java)
intent2.putExtra("id", userData.id)
intent2.putExtra("user", userData.name)
intent2.putExtra("password", userData.password)
intent2.putExtra("login", userData.login)
startActivity(intent2)
} else {
val message = "未在数据库中找到对应的账户数据!\n请先完成账户注册!"
val alertDialog = AlertDialog.Builder(this)
.setTitle("登录失败")
.setMessage(message)
.setPositiveButton("确定", null)
.create()
alertDialog.show()
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M240,760L360,760L360,560Q360,543 371.5,531.5Q383,520 400,520L560,520Q577,520 588.5,531.5Q600,543 600,560L600,760L720,760L720,400Q720,400 720,400Q720,400 720,400L480,220Q480,220 480,220Q480,220 480,220L240,400Q240,400 240,400Q240,400 240,400L240,760ZM160,760L160,400Q160,381 168.5,364Q177,347 192,336L432,156Q453,140 480,140Q507,140 528,156L768,336Q783,347 791.5,364Q800,381 800,400L800,760Q800,793 776.5,816.5Q753,840 720,840L560,840Q543,840 531.5,828.5Q520,817 520,800L520,600Q520,600 520,600Q520,600 520,600L440,600Q440,600 440,600Q440,600 440,600L440,800Q440,817 428.5,828.5Q417,840 400,840L240,840Q207,840 183.5,816.5Q160,793 160,760ZM480,490L480,490L480,490Q480,490 480,490Q480,490 480,490L480,490L480,490L480,490L480,490Q480,490 480,490Q480,490 480,490L480,490Q480,490 480,490Q480,490 480,490L480,490L480,490Z"/>
</vector>

View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View File

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M480,480Q414,480 367,433Q320,386 320,320Q320,254 367,207Q414,160 480,160Q546,160 593,207Q640,254 640,320Q640,386 593,433Q546,480 480,480ZM720,800L240,800Q207,800 183.5,776.5Q160,753 160,720L160,688Q160,654 177.5,625.5Q195,597 224,582Q286,551 350,535.5Q414,520 480,520Q546,520 610,535.5Q674,551 736,582Q765,597 782.5,625.5Q800,654 800,688L800,720Q800,753 776.5,776.5Q753,800 720,800ZM240,720L720,720L720,688Q720,677 714.5,668Q709,659 700,654Q646,627 591,613.5Q536,600 480,600Q424,600 369,613.5Q314,627 260,654Q251,659 245.5,668Q240,677 240,688L240,720ZM480,400Q513,400 536.5,376.5Q560,353 560,320Q560,287 536.5,263.5Q513,240 480,240Q447,240 423.5,263.5Q400,287 400,320Q400,353 423.5,376.5Q447,400 480,400ZM480,320Q480,320 480,320Q480,320 480,320Q480,320 480,320Q480,320 480,320Q480,320 480,320Q480,320 480,320Q480,320 480,320Q480,320 480,320ZM480,720L480,720Q480,720 480,720Q480,720 480,720Q480,720 480,720Q480,720 480,720Q480,720 480,720Q480,720 480,720Q480,720 480,720Q480,720 480,720L480,720L480,720Z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

@ -0,0 +1,374 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="75dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/topAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="万物互联 " />
</com.google.android.material.appbar.AppBarLayout>
<!-- Note: A RecyclerView can also be used -->
<!-- Scrollable content -->
</androidx.core.widget.NestedScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
tools:ignore="MissingConstraints">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:id="@+id/card24"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/title"
android:text="日报"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:id="@+id/tianqi"
android:text="今日天气 良好 温度18-20°C"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:id="@+id/yinyu"
android:text="Have a nice day!"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<Button
android:id="@+id/buttonadd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加设备"
android:onClick="adddive"/>
<com.google.android.material.card.MaterialCardView
android:id="@+id/card1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp"
android:id="@+id/sda1q2">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我的设备"
android:textAppearance="?attr/textAppearanceTitleMedium" />
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="我们的产品"
android:layout_marginTop="3dp"
android:gravity="center"
android:textSize="20dp" />
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:orientation="vertical">
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="智能植物培育设备"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="全新一代智慧化AI花盆"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="丰富的拟人表情"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="主动环境控制"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="AI全向预测与调控"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:src="@drawable/flowerpot"/>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:orientation="vertical">
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="YANG-SSD硬盘盒"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="可视化智能硬盘盒"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="生活信息即时显示"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="每日天气"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="每日一言"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:src="@drawable/yangssd"/> />
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="64dp"
android:orientation="vertical">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:menu="@menu/bottom_navigation_menu" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,324 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/topAppBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:title="添加设备 " />
</com.google.android.material.appbar.AppBarLayout>
<!-- Note: A RecyclerView can also be used -->
<!-- Scrollable content -->
</androidx.core.widget.NestedScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
tools:ignore="MissingConstraints">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:id="@+id/card24"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/title"
android:text="设备绑定"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:id="@+id/textView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="输入设备ID" />
<EditText
android:id="@+id/editTextText2231"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text"
android:text="" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="输入名称:" />
<EditText
android:id="@+id/fpeditTextText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text"
android:text="" />
<Button
android:id="@+id/button22331"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="绑定设备"
android:onClick="addid"/>
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="新品预览"
android:layout_marginTop="3dp"
android:gravity="center"
android:textSize="20dp"
/>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:orientation="vertical">
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="智能植物培育设备"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="全新一代智慧化AI花盆"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="丰富的拟人表情"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="主动环境控制"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="AI全向预测与调控"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:src="@drawable/flowerpot"/>
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="了解更多" />
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:orientation="vertical">
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="YANG-SSD硬盘盒"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="可视化智能硬盘盒"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="生活信息即时显示"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="每日天气"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="每日一言"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:src="@drawable/yangssd"/> />
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="了解更多" />
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</ScrollView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,265 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/topAppBar"
android:layout_width="match_parent"
android:layout_height="74dp"
app:title="Flowerpot " />
</com.google.android.material.appbar.AppBarLayout>
<!-- Note: A RecyclerView can also be used -->
<!-- Scrollable content -->
</androidx.core.widget.NestedScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
tools:ignore="MissingConstraints">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:orientation="vertical">
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="智能植物培育设备"
android:textSize="20dp"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="设备ID"
android:id="@+id/dvid"
android:textSize="20dp"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="设备状态:"
android:textSize="20dp"
android:id="@+id/dvst"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="固件版本:"
android:textSize="20dp"
android:id="@+id/dvinfo"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginBottom="5dp"
android:textSize="18dp"
android:layout_marginLeft="8dp"
android:text="你的植物似乎很开心"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:src="@drawable/flowerpot"/>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/card1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AI交互实验性功能"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="230dp" >
<TextView
android:id="@+id/aichatx"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="请先在聊天框提问,并点击发送。" />
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
</LinearLayout>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/card24"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/title"
android:text="聊天框"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<EditText
android:id="@+id/aichattext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text"
/>
<Button
android:id="@+id/buttonadd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送"
android:onClick="addaichat"/>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</ScrollView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DBStart">
<TextView
android:id="@+id/show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.25" />
<Button
android:id="@+id/add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="增"
android:textSize="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.74" />
<Button
android:id="@+id/query"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="查"
android:textSize="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/add" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,797 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/topAppBar"
android:layout_width="match_parent"
android:layout_height="74dp"
app:title="万物互联IOT移动端 " />
</com.google.android.material.appbar.AppBarLayout>
<!-- Note: A RecyclerView can also be used -->
<!-- Scrollable content -->
</androidx.core.widget.NestedScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
tools:ignore="MissingConstraints">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:orientation="vertical">
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="智能植物培育设备"
android:textSize="20dp"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:textSize="20dp"
android:layout_marginLeft="8dp"
android:text="植物名称:"
android:id="@+id/fpname1"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="设备ID"
android:id="@+id/dvid"
android:textSize="20dp"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="设备状态:"
android:textSize="20dp"
android:id="@+id/dvst"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="固件版本:"
android:textSize="20dp"
android:id="@+id/dvinfo"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:src="@drawable/flowerpot"/>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="130dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="环境温度"
android:textAppearance="?attr/textAppearanceTitleMedium" />
</LinearLayout>
<TextView
android:id="@+id/tmpfp"
android:layout_width="121dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="0.00°C"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary"
android:textSize="30dp" />
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="130dp"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="土壤湿度"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:id="@+id/hmfp"
android:layout_width="121dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="0.00%"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary"
android:textSize="30dp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="130dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="环境湿度"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:id="@+id/hmpfp"
android:layout_width="109dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="0.00%"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary"
android:textSize="30dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
<com.google.android.material.card.MaterialCardView
android:id="@+id/card1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AI交互实验性功能"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:onClick="aichatbton">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="84dp"
android:layout_height="wrap_content"
android:text="AI交互聊天"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:id="@+id/alchatbt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="关"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary"
android:textSize="30dp" />
</LinearLayout>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:onClick="aichatbton">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<LinearLayout
android:layout_width="120dp"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="84dp"
android:layout_height="wrap_content"
android:text="AI视觉预测"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:id="@+id/aiseebt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="关"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary"
android:textSize="30dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/card2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="控制台"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:onClick="autobton">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="248dp"
android:layout_height="wrap_content"
android:text="AUTO自动控制"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:id="@+id/autobt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="关"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary"
android:textSize="30dp" />
</LinearLayout>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:onClick="tmpbton">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="84dp"
android:layout_height="wrap_content"
android:text="环境恒温"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:id="@+id/tmpbt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="关"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary"
android:textSize="30dp" />
</LinearLayout>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:onClick="lightbton">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<LinearLayout
android:layout_width="120dp"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="84dp"
android:layout_height="wrap_content"
android:text="环境光照"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:id="@+id/lightbt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="关"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary"
android:textSize="30dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:onClick="waterbton">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<LinearLayout
android:layout_width="117dp"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="84dp"
android:layout_height="wrap_content"
android:text="浇水"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:id="@+id/waterbt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="关"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary"
android:textSize="30dp" />
</LinearLayout>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:onClick="updatebton">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="150dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="68dp"
android:layout_height="wrap_content"
android:text="更新"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:id="@+id/updt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="当前版本V0.0.0" />
</LinearLayout>
<TextView
android:id="@+id/upbt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="*"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary"
android:textSize="30dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</ScrollView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,496 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/topAppBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:title="Flowerpot使用说明" />
</com.google.android.material.appbar.AppBarLayout>
<!-- Note: A RecyclerView can also be used -->
<!-- Scrollable content -->
</androidx.core.widget.NestedScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
tools:ignore="MissingConstraints">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="初次使用"
android:layout_marginTop="3dp"
android:gravity="center"
android:textSize="20dp"
/>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:orientation="vertical">
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="步骤一"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="1.为你的设备插入电源"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="2.等待设备从开机动画进入表情界面"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="3.点击HOME键2次进入WIFI配对模式"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:src="@drawable/flowerpot"/>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="注意请确保您需要联网的WIFI可以上网并无需浏览器认证" />
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:orientation="vertical">
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="步骤二"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="1.打开手机WIFI连接到名称为”Flowerpot“的WIFI网络"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="2.进入网络认证界面选择需要联网的WIFI名并输入密码。"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="3.点击Save按钮等待设备重启即可"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:src="@drawable/yangssd"/> />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:orientation="vertical">
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="步骤三"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="1.点击HOME键进入P4设备信息界面"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="2.在APP添加设备中输入设备信息界面显示的的设备ID号"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="3.大功告成,现在你可以使用远程控制及在线功能了!"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:src="@drawable/yangssd"/> />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="网络更换"
android:layout_marginTop="3dp"
android:gravity="center"
android:textSize="20dp"
/>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:orientation="vertical">
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="步骤一"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="ss"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="生活信息即时显示"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="每日天气"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="每日一言"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:src="@drawable/yangssd"/> />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:orientation="vertical">
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="步骤二"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="可视化智能硬盘盒"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="生活信息即时显示"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="每日天气"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="每日一言"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:src="@drawable/yangssd"/> />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</ScrollView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="841dp"
android:layout_weight="1"
tools:ignore="MissingConstraints">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:gravity="center"
android:text="万物互联"
android:textSize="150px" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/textField"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:hint="请输入账户名"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="0dp">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/textField2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="请输入密码"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="0dp">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"/>
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="50px"
android:layout_marginRight="140px"
android:layout_marginLeft="150px"
android:layout_weight="1"
android:text="注册" />
<Button
android:id="@+id/button5"
android:layout_width="138dp"
android:layout_height="match_parent"
android:layout_marginTop="50px"
android:layout_marginRight="150px"
android:text="登录"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="64dp"
android:orientation="vertical">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:menu="@menu/bottom_navigation_menu" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,319 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="81dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/topAppBar"
android:layout_width="match_parent"
android:layout_height="82dp"
app:title="更新" />
</com.google.android.material.appbar.AppBarLayout>
<!-- Note: A RecyclerView can also be used -->
<!-- Scrollable content -->
</androidx.core.widget.NestedScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
tools:ignore="MissingConstraints">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:orientation="vertical">
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:id="@+id/uptitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="智能植物培育设备"
android:textSize="20dp"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="设备ID"
android:id="@+id/updvid"
android:textSize="20dp"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="设备状态:"
android:textSize="20dp"
android:id="@+id/updvst"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginLeft="8dp"
android:text="固件版本:"
android:textSize="20dp"
android:id="@+id/updvinfo"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginBottom="5dp"
android:textSize="18dp"
android:layout_marginLeft="8dp"
android:text="*更新时请不要退出*"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:src="@drawable/flowerpot"/>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="200dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="当前版本"
android:textAppearance="?attr/textAppearanceTitleMedium" />
</LinearLayout>
<TextView
android:id="@+id/uplocation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="V0.0.0"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary"
android:textSize="30dp" />
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="最新版本"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:id="@+id/uponline"
android:layout_width="121dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="V0.0.0"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary"
android:textSize="30dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
<Button
android:id="@+id/updatebt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="检查更新"
android:onClick="update"/>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="控制台"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:id="@+id/updateinfo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="更新日志:" />
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</ScrollView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,194 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:orientation="vertical">
<!-- Title, secondary and supporting text -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="用户User"
android:id="@+id/user"
android:textAppearance="?attr/textAppearanceTitleMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text="欢迎"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:text=""
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
tools:srcCompat="@tools:sample/avatars" />
</LinearLayout>
<!-- Buttons -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
style="?attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="退出登录"
android:id="@+id/out"/>
<com.google.android.material.button.MaterialButton
style="?attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="注销" />
<com.google.android.material.button.MaterialButton
style="?attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="更换头像"
android:id="@+id/img"/>
<com.google.android.material.button.MaterialButton
style="?attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="更换昵称"
android:id="@+id/name"/>
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:onClick="toupdate">
<!-- Media -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<!-- Title, secondary and supporting text -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="243dp"
android:layout_height="wrap_content"
android:text="更新应用程序"
android:textAppearance="?attr/textAppearanceTitleMedium"
android:textSize="20dp" />
<TextView
android:id="@+id/updateinfo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="检查更新"
android:textSize="18dp"/>
</LinearLayout>
</LinearLayout>
<!-- Buttons -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="64dp"
android:orientation="vertical">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:menu="@menu/bottom_navigation_menu" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/item_1"
android:enabled="true"
android:icon="@drawable/home"
android:title="万物互联"/>
<item
android:id="@+id/item_2"
android:enabled="true"
android:icon="@drawable/person"
android:title="个人中心"/>
</menu>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/edit"
android:title="@string/login"
android:contentDescription="string/content_description_search"
app:showAsAction="ifRoom" />
<item
android:id="@+id/favorite"
android:title="@string/register"
android:contentDescription="string/content_description_favorite"
app:showAsAction="ifRoom" />
<item
android:id="@+id/more"
android:title="@string/more"
android:contentDescription="string/content_description_more"
app:showAsAction="never" />
<item
android:id="@+id/more2"
android:title="@string/more"
android:contentDescription="string/content_description_more"
app:showAsAction="never" />
</menu>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,34 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Base.Theme.MyApplication" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your dark theme here. -->
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
<item name="colorPrimary">@color/md_theme_dark_primary</item>
<item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/md_theme_dark_onPrimaryContainer</item>
<item name="colorSecondary">@color/md_theme_dark_secondary</item>
<item name="colorOnSecondary">@color/md_theme_dark_onSecondary</item>
<item name="colorSecondaryContainer">@color/md_theme_dark_secondaryContainer</item>
<item name="colorOnSecondaryContainer">@color/md_theme_dark_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_dark_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_dark_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_dark_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_dark_onTertiaryContainer</item>
<item name="colorError">@color/md_theme_dark_error</item>
<item name="colorErrorContainer">@color/md_theme_dark_errorContainer</item>
<item name="colorOnError">@color/md_theme_dark_onError</item>
<item name="colorOnErrorContainer">@color/md_theme_dark_onErrorContainer</item>
<item name="android:colorBackground">@color/md_theme_dark_background</item>
<item name="colorOnBackground">@color/md_theme_dark_onBackground</item>
<item name="colorOutline">@color/md_theme_dark_outline</item>
<item name="colorOnSurfaceInverse">@color/md_theme_dark_inverseOnSurface</item>
<item name="colorSurfaceInverse">@color/md_theme_dark_inverseSurface</item>
<item name="colorSurface">@color/md_theme_dark_surface</item>
<item name="colorOnSurface">@color/md_theme_dark_onSurface</item>
<item name="colorSurfaceVariant">@color/md_theme_dark_surfaceVariant</item>
<item name="colorOnSurfaceVariant">@color/md_theme_dark_onSurfaceVariant</item>
<item name="colorPrimaryInverse">@color/md_theme_dark_inversePrimary</item>
<item name="android:statusBarColor">@color/md_theme_dark_surface</item>
</style>
</resources>

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="seed">#6750A4</color>
<color name="md_theme_light_primary">#6750A4</color>
<color name="md_theme_light_onPrimary">#FFFFFF</color>
<color name="md_theme_light_primaryContainer">#E9DDFF</color>
<color name="md_theme_light_onPrimaryContainer">#22005D</color>
<color name="md_theme_light_secondary">#625B71</color>
<color name="md_theme_light_onSecondary">#FFFFFF</color>
<color name="md_theme_light_secondaryContainer">#E8DEF8</color>
<color name="md_theme_light_onSecondaryContainer">#1E192B</color>
<color name="md_theme_light_tertiary">#7E5260</color>
<color name="md_theme_light_onTertiary">#FFFFFF</color>
<color name="md_theme_light_tertiaryContainer">#FFD9E3</color>
<color name="md_theme_light_onTertiaryContainer">#31101D</color>
<color name="md_theme_light_error">#BA1A1A</color>
<color name="md_theme_light_errorContainer">#FFDAD6</color>
<color name="md_theme_light_onError">#FFFFFF</color>
<color name="md_theme_light_onErrorContainer">#410002</color>
<color name="md_theme_light_background">#FFFBFF</color>
<color name="md_theme_light_onBackground">#1C1B1E</color>
<color name="md_theme_light_outline">#7A757F</color>
<color name="md_theme_light_inverseOnSurface">#F4EFF4</color>
<color name="md_theme_light_inverseSurface">#313033</color>
<color name="md_theme_light_inversePrimary">#CFBCFF</color>
<color name="md_theme_light_shadow">#000000</color>
<color name="md_theme_light_surfaceTint">#6750A4</color>
<color name="md_theme_light_outlineVariant">#CAC4CF</color>
<color name="md_theme_light_scrim">#000000</color>
<color name="md_theme_light_surface">#FDF8FD</color>
<color name="md_theme_light_onSurface">#1C1B1E</color>
<color name="md_theme_light_surfaceVariant">#E7E0EB</color>
<color name="md_theme_light_onSurfaceVariant">#49454E</color>
<color name="md_theme_dark_primary">#CFBCFF</color>
<color name="md_theme_dark_onPrimary">#381E72</color>
<color name="md_theme_dark_primaryContainer">#4F378A</color>
<color name="md_theme_dark_onPrimaryContainer">#E9DDFF</color>
<color name="md_theme_dark_secondary">#CBC2DB</color>
<color name="md_theme_dark_onSecondary">#332D41</color>
<color name="md_theme_dark_secondaryContainer">#4A4458</color>
<color name="md_theme_dark_onSecondaryContainer">#E8DEF8</color>
<color name="md_theme_dark_tertiary">#EFB8C8</color>
<color name="md_theme_dark_onTertiary">#4A2532</color>
<color name="md_theme_dark_tertiaryContainer">#633B48</color>
<color name="md_theme_dark_onTertiaryContainer">#FFD9E3</color>
<color name="md_theme_dark_error">#FFB4AB</color>
<color name="md_theme_dark_errorContainer">#93000A</color>
<color name="md_theme_dark_onError">#690005</color>
<color name="md_theme_dark_onErrorContainer">#FFDAD6</color>
<color name="md_theme_dark_background">#1C1B1E</color>
<color name="md_theme_dark_onBackground">#E6E1E6</color>
<color name="md_theme_dark_outline">#948F99</color>
<color name="md_theme_dark_inverseOnSurface">#1C1B1E</color>
<color name="md_theme_dark_inverseSurface">#E6E1E6</color>
<color name="md_theme_dark_inversePrimary">#6750A4</color>
<color name="md_theme_dark_shadow">#000000</color>
<color name="md_theme_dark_surfaceTint">#CFBCFF</color>
<color name="md_theme_dark_outlineVariant">#49454E</color>
<color name="md_theme_dark_scrim">#000000</color>
<color name="md_theme_dark_surface">#141316</color>
<color name="md_theme_dark_onSurface">#CAC5CA</color>
<color name="md_theme_dark_surfaceVariant">#49454E</color>
<color name="md_theme_dark_onSurfaceVariant">#CAC4CF</color>
</resources>

View File

@ -0,0 +1,9 @@
<resources>
<string name="app_name">My Application</string>
<string name="login">项目开发:</string>
<string name="register">YANG</string>
<string name="more">更多</string>
<string name="content_description_search">搜索</string>
<string name="content_description_favorite">收藏</string>
<string name="content_description_more">更多</string>
</resources>

View File

@ -0,0 +1,36 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Base.Theme.MyApplication" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your light theme here. -->
<item name="colorPrimary">@color/md_theme_light_primary</item>
<item name="colorOnPrimary">@color/md_theme_light_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_light_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/md_theme_light_onPrimaryContainer</item>
<item name="colorSecondary">@color/md_theme_light_secondary</item>
<item name="colorOnSecondary">@color/md_theme_light_onSecondary</item>
<item name="colorSecondaryContainer">@color/md_theme_light_secondaryContainer</item>
<item name="colorOnSecondaryContainer">@color/md_theme_light_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_light_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_light_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_light_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_light_onTertiaryContainer</item>
<item name="colorError">@color/md_theme_light_error</item>
<item name="colorErrorContainer">@color/md_theme_light_errorContainer</item>
<item name="colorOnError">@color/md_theme_light_onError</item>
<item name="colorOnErrorContainer">@color/md_theme_light_onErrorContainer</item>
<item name="android:colorBackground">@color/md_theme_light_background</item>
<item name="colorOnBackground">@color/md_theme_light_onBackground</item>
<item name="colorOutline">@color/md_theme_light_outline</item>
<item name="colorOnSurfaceInverse">@color/md_theme_light_inverseOnSurface</item>
<item name="colorSurfaceInverse">@color/md_theme_light_inverseSurface</item>
<item name="colorSurface">@color/md_theme_light_surface</item>
<item name="colorOnSurface">@color/md_theme_light_onSurface</item>
<item name="colorSurfaceVariant">@color/md_theme_light_surfaceVariant</item>
<item name="colorOnSurfaceVariant">@color/md_theme_light_onSurfaceVariant</item>
<item name="colorPrimaryInverse">@color/md_theme_light_inversePrimary</item>
<item name="android:statusBarColor">@color/md_theme_light_surface</item>
</style>
<style name="Theme.MyApplication" parent="Base.Theme.MyApplication" />
</resources>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older that API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample data extraction rules file; uncomment and customize as necessary.
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
for details.
-->
<data-extraction-rules>
<cloud-backup>
<!-- TODO: Use <include> and <exclude> to control what is backed up.
<include .../>
<exclude .../>
-->
</cloud-backup>
<!--
<device-transfer>
<include .../>
<exclude .../>
</device-transfer>
-->
</data-extraction-rules>

View File

@ -0,0 +1,17 @@
package com.example.IOTsmart
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

6
build.gradle.kts Normal file
View File

@ -0,0 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.application") version "8.5.0-alpha08" apply false
id("org.jetbrains.kotlin.android") version "1.9.0" apply false
id("com.google.devtools.ksp") version "1.9.21-1.0.16" apply false
}

23
gradle.properties Normal file
View File

@ -0,0 +1,23 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,6 @@
#Tue Aug 29 12:21:59 CST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
gradlew vendored Normal file
View File

@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
gradlew.bat vendored Normal file
View File

@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

8
local.properties Normal file
View File

@ -0,0 +1,8 @@
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Sun Sep 17 13:35:17 CST 2023
sdk.dir=C\:\\Users\\qw200\\AppData\\Local\\Android\\Sdk

18
settings.gradle.kts Normal file
View File

@ -0,0 +1,18 @@
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "My Application"
include(":app")