commit
6
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="17" />
|
||||
</component>
|
||||
</project>
|
||||
16
.idea/gradle.xml
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
<?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="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
13
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="FrameworkDetectionExcludesConfiguration">
|
||||
<file type="web" url="file://$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
||||
124
.idea/uiDesigner.xml
generated
Normal file
@@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal 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>
|
||||
75
app/build.gradle
Normal file
@@ -0,0 +1,75 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'org.astral.findmaimaiultra'
|
||||
compileSdk 33
|
||||
|
||||
defaultConfig {
|
||||
applicationId "org.astral.findmaimaiultra"
|
||||
minSdk 30
|
||||
targetSdk 33
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
// 自定义打包名称
|
||||
android.applicationVariants.all { variant ->
|
||||
variant.outputs.all {
|
||||
outputFileName = "FindMaiMaiDXPhone_${buildType.name}_v${versionName}.apk"
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
defaultConfig {
|
||||
ndk {
|
||||
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86","x86_64"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.gms:play-services-location:21.0.1'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.9.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.3.2'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
implementation 'com.otaliastudios:zoomlayout:1.9.0'
|
||||
implementation 'androidx.work:work-runtime:2.7.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
|
||||
implementation 'com.google.code.gson:gson:2.8.8'
|
||||
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
|
||||
implementation 'org.nanohttpd:nanohttpd:2.2.0'
|
||||
implementation 'com.baidu.lbsyun:BaiduMapSDK_Map:7.6.3'
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1'
|
||||
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
|
||||
implementation 'com.github.yalantis:ucrop:2.2.8'
|
||||
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.8.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.navigation:navigation-fragment:2.5.3'
|
||||
implementation 'androidx.navigation:navigation-ui:2.5.3'
|
||||
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
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.astral.findmaimaiultra;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
assertEquals("org.astral.findmaimaiultra", appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
64
app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,64 @@
|
||||
<?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.MANAGE_EXTERNAL_STORAGE"/>
|
||||
<!-- 允许获取精确位置,精准定位必选 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<!-- 后台获取位置信息,若需后台定位则必选 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<!-- 用于申请调用A-GPS模块,卫星定位加速 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="35"
|
||||
tools:ignore="ScopedStorage"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="35"/>
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" tools:ignore="ProtectedPermissions"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions"/>
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
tools:targetApi="34"
|
||||
android:hardwareAccelerated="true"
|
||||
android:label="@string/app_name"
|
||||
android:persistent="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:roundIcon="@drawable/ic_launcher"
|
||||
android:supportsRtl="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:theme="@style/Theme.FindMaimaiUltra">
|
||||
<activity
|
||||
android:name=".ui.MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.FindMaimaiUltra.NoActionBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.PageActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.FindMaimaiUltra.NoActionBar">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.LinkQQBot"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.FindMaimaiUltra.NoActionBar">
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,152 @@
|
||||
package org.astral.findmaimaiultra.adapter;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.constraintlayout.widget.ConstraintSet;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.astral.findmaimaiultra.R;
|
||||
import org.astral.findmaimaiultra.been.Place;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PlaceAdapter extends RecyclerView.Adapter<PlaceAdapter.PlaceViewHolder> {
|
||||
|
||||
private List<Place> placeList;
|
||||
private OnItemClickListener listener;
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onItemClick(Place place);
|
||||
}
|
||||
|
||||
public PlaceAdapter(List<Place> placeList, OnItemClickListener listener) {
|
||||
this.placeList = placeList;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public PlaceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_place, parent, false);
|
||||
return new PlaceViewHolder(itemView);
|
||||
}
|
||||
|
||||
@SuppressLint({"SetTextI18n", "UseCompatLoadingForDrawables"})
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull PlaceViewHolder holder, int position) {
|
||||
Place place = placeList.get(position);
|
||||
if (place.getIsUse()==0) {
|
||||
holder.nameTextView.setTextColor(ContextCompat.getColor(holder.itemView.getContext(), R.color.red));
|
||||
}
|
||||
if (place.getName().contains("收藏")) {
|
||||
holder.nameTextView.setText(place.getName() + "♥");
|
||||
} else {
|
||||
holder.nameTextView.setText(place.getName());
|
||||
}
|
||||
holder.provinceTextView.setText(place.getProvince());
|
||||
holder.cityTextView.setText(place.getCity());
|
||||
holder.areaTextView.setText(place.getArea());
|
||||
holder.addressTextView.setText(place.getAddress());
|
||||
double rating = (double) ((place.getNum() + place.getNumJ()) * (place.getGood() + 1)) / (place.getGood() + place.getBad() + 1);
|
||||
Log.i("rating", rating + "");
|
||||
if (rating >= 3) {
|
||||
holder.imageView.setImageDrawable(ContextCompat.getDrawable(holder.itemView.getContext(), R.drawable.rank_sssp));
|
||||
} else if (rating < 3 && rating >= 2) {
|
||||
holder.imageView.setImageDrawable(ContextCompat.getDrawable(holder.itemView.getContext(), R.drawable.rank_sss));
|
||||
} else if (rating < 2 && rating >= 1) {
|
||||
holder.imageView.setImageDrawable(ContextCompat.getDrawable(holder.itemView.getContext(), R.drawable.rank_ss));
|
||||
} else if (rating < 1 && rating >= 0.5) {
|
||||
holder.imageView.setImageDrawable(ContextCompat.getDrawable(holder.itemView.getContext(), R.drawable.rank_s));
|
||||
} else if (rating < 0.5 && rating >= 0) {
|
||||
holder.imageView.setImageDrawable(ContextCompat.getDrawable(holder.itemView.getContext(), R.drawable.rank_s));
|
||||
} else {
|
||||
holder.imageView.setImageDrawable(ContextCompat.getDrawable(holder.itemView.getContext(), R.drawable.rank_a));
|
||||
}
|
||||
Log.i("rating", rating + "|" + place.getName());
|
||||
// 控制竖线的位置
|
||||
controlVerticalLines(holder, place);
|
||||
|
||||
// 设置点击监听器
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onItemClick(place);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void controlVerticalLines(PlaceViewHolder holder, Place place) {
|
||||
ConstraintLayout horizontalLinesContainer = holder.itemView.findViewById(R.id.horizontalLinesContainer);
|
||||
ConstraintSet constraintSet = new ConstraintSet();
|
||||
constraintSet.clone(horizontalLinesContainer);
|
||||
|
||||
double rating = (double) ((place.getNum() + place.getNumJ()) * (place.getGood() + 5)) / (place.getBad() + 5);
|
||||
// 根据 rating 计算竖线的位置百分比
|
||||
float bias1 = (float) (rating / 3.0); // 示例百分比,假设 rating 最大为 3
|
||||
float bias2 = (float) (2 * rating / 3.0); // 示例百分比,假设 rating 最大为 3
|
||||
float bias3 = 1.0f; // 第三条竖线始终在最右边
|
||||
|
||||
// 确保 bias 不超过 1.0
|
||||
bias1 = Math.min(bias1, 1.0f);
|
||||
bias2 = Math.min(bias2, 1.0f);
|
||||
|
||||
// 设置 Guideline 的位置
|
||||
constraintSet.setGuidelinePercent(R.id.guideline1, bias1);
|
||||
constraintSet.setGuidelinePercent(R.id.guideline2, bias2);
|
||||
constraintSet.setGuidelinePercent(R.id.guideline3, bias3);
|
||||
|
||||
if (rating >= 3) {
|
||||
// 显示所有竖线
|
||||
constraintSet.setVisibility(R.id.verticalLine1, View.VISIBLE);
|
||||
constraintSet.setVisibility(R.id.verticalLine2, View.VISIBLE);
|
||||
constraintSet.setVisibility(R.id.verticalLine3, View.VISIBLE);
|
||||
} else if (rating < 3 && rating >= 2) {
|
||||
// 显示前两条竖线
|
||||
constraintSet.setVisibility(R.id.verticalLine1, View.VISIBLE);
|
||||
constraintSet.setVisibility(R.id.verticalLine2, View.VISIBLE);
|
||||
constraintSet.setVisibility(R.id.verticalLine3, View.GONE);
|
||||
} else if (rating < 2 && rating >= 1) {
|
||||
// 显示第一条竖线
|
||||
constraintSet.setVisibility(R.id.verticalLine1, View.VISIBLE);
|
||||
constraintSet.setVisibility(R.id.verticalLine2, View.GONE);
|
||||
constraintSet.setVisibility(R.id.verticalLine3, View.GONE);
|
||||
} else {
|
||||
// 不显示竖线
|
||||
constraintSet.setVisibility(R.id.verticalLine1, View.GONE);
|
||||
constraintSet.setVisibility(R.id.verticalLine2, View.GONE);
|
||||
constraintSet.setVisibility(R.id.verticalLine3, View.GONE);
|
||||
}
|
||||
|
||||
constraintSet.applyTo(horizontalLinesContainer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return placeList.size();
|
||||
}
|
||||
|
||||
static class PlaceViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView nameTextView;
|
||||
TextView provinceTextView;
|
||||
TextView cityTextView;
|
||||
TextView areaTextView;
|
||||
TextView addressTextView;
|
||||
ImageView imageView;
|
||||
|
||||
PlaceViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
nameTextView = itemView.findViewById(R.id.nameTextView);
|
||||
provinceTextView = itemView.findViewById(R.id.provinceTextView);
|
||||
cityTextView = itemView.findViewById(R.id.cityTextView);
|
||||
areaTextView = itemView.findViewById(R.id.areaTextView);
|
||||
addressTextView = itemView.findViewById(R.id.addressTextView);
|
||||
imageView = itemView.findViewById(R.id.photoId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package org.astral.findmaimaiultra.adapter;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.astral.findmaimaiultra.been.PlaceContent;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ReviewAdapter extends RecyclerView.Adapter<ReviewAdapter.ViewHolder> {
|
||||
|
||||
private List<PlaceContent> reviews;
|
||||
|
||||
public ReviewAdapter(List<PlaceContent> reviews) {
|
||||
this.reviews = reviews;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_2, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
PlaceContent review = reviews.get(position);
|
||||
if(review.isUsed()) {
|
||||
holder.textViewUser.setText(review.getUser_name());
|
||||
holder.textViewContent.setText(review.getUser_content());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return reviews.size();
|
||||
}
|
||||
|
||||
public void addReview(PlaceContent review) {
|
||||
reviews.add(review);
|
||||
notifyItemInserted(reviews.size() - 1);
|
||||
}
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView textViewUser;
|
||||
TextView textViewContent;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
textViewUser = itemView.findViewById(android.R.id.text1);
|
||||
textViewContent = itemView.findViewById(android.R.id.text2);
|
||||
|
||||
textViewUser.setTextSize(18);
|
||||
textViewContent.setTextSize(14);
|
||||
}
|
||||
}
|
||||
}
|
||||
50
app/src/main/java/org/astral/findmaimaiultra/been/AiLog.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
public class AiLog {
|
||||
private long id;
|
||||
private String x;
|
||||
private String y;
|
||||
private String androidId;
|
||||
private String message;
|
||||
private String time;
|
||||
|
||||
public String getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(String x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public String getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(String y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public String getAndroidId() {
|
||||
return androidId;
|
||||
}
|
||||
|
||||
public void setAndroidId(String androidId) {
|
||||
this.androidId = androidId;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(String time) {
|
||||
this.time = time;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
public class AiUserMessage {
|
||||
private String Time;
|
||||
private String Message;
|
||||
|
||||
public String getTime() {
|
||||
return Time;
|
||||
}
|
||||
|
||||
public void setTime(String time) {
|
||||
Time = time;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return Message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
Message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AmapReverseGeocodeResponse {
|
||||
private String status;
|
||||
private String info;
|
||||
private Regeocode regeocode;
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public Regeocode getRegeocode() {
|
||||
return regeocode;
|
||||
}
|
||||
|
||||
public static class Regeocode {
|
||||
private String formatted_address;
|
||||
private AddressComponent addressComponent;
|
||||
|
||||
public String getFormattedAddress() {
|
||||
return formatted_address;
|
||||
}
|
||||
|
||||
public AddressComponent getAddressComponent() {
|
||||
return addressComponent;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AddressComponent {
|
||||
private String province;
|
||||
private List<String> city;
|
||||
|
||||
public String getProvince() {
|
||||
return province;
|
||||
}
|
||||
|
||||
public List<String> getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setProvince(String province) {
|
||||
this.province = province;
|
||||
}
|
||||
|
||||
public void setCity(List<String> city) {
|
||||
this.city = city;
|
||||
}
|
||||
}
|
||||
}
|
||||
138
app/src/main/java/org/astral/findmaimaiultra/been/Chart.java
Normal file
@@ -0,0 +1,138 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Chart {
|
||||
@SerializedName("achievements")
|
||||
private double achievements;
|
||||
@SerializedName("ds")
|
||||
private double ds;
|
||||
@SerializedName("dxScore")
|
||||
private int dxScore;
|
||||
@SerializedName("fc")
|
||||
private String fc;
|
||||
@SerializedName("fs")
|
||||
private String fs;
|
||||
@SerializedName("level")
|
||||
private String level;
|
||||
@SerializedName("level_index")
|
||||
private int level_index;
|
||||
@SerializedName("level_label")
|
||||
private String levelLabel;
|
||||
@SerializedName("ra")
|
||||
private int ra;
|
||||
@SerializedName("rate")
|
||||
private String rate;
|
||||
@SerializedName("song_id")
|
||||
private int songId;
|
||||
@SerializedName("title")
|
||||
private String title;
|
||||
@SerializedName("type")
|
||||
private String type;
|
||||
|
||||
public double getAchievements() {
|
||||
return achievements;
|
||||
}
|
||||
|
||||
public void setAchievements(double achievements) {
|
||||
this.achievements = achievements;
|
||||
}
|
||||
|
||||
public double getDs() {
|
||||
return ds;
|
||||
}
|
||||
|
||||
public void setDs(double ds) {
|
||||
this.ds = ds;
|
||||
}
|
||||
|
||||
public int getDxScore() {
|
||||
return dxScore;
|
||||
}
|
||||
|
||||
public void setDxScore(int dxScore) {
|
||||
this.dxScore = dxScore;
|
||||
}
|
||||
|
||||
public String getFc() {
|
||||
return fc;
|
||||
}
|
||||
|
||||
public void setFc(String fc) {
|
||||
this.fc = fc;
|
||||
}
|
||||
|
||||
public String getFs() {
|
||||
return fs;
|
||||
}
|
||||
|
||||
public void setFs(String fs) {
|
||||
this.fs = fs;
|
||||
}
|
||||
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(String level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public int getLevel_index() {
|
||||
return level_index;
|
||||
}
|
||||
|
||||
public void setLevel_index(int level_index) {
|
||||
this.level_index = level_index;
|
||||
}
|
||||
|
||||
public String getLevelLabel() {
|
||||
return levelLabel;
|
||||
}
|
||||
|
||||
public void setLevelLabel(String levelLabel) {
|
||||
this.levelLabel = levelLabel;
|
||||
}
|
||||
|
||||
public int getRa() {
|
||||
return ra;
|
||||
}
|
||||
|
||||
public void setRa(int ra) {
|
||||
this.ra = ra;
|
||||
}
|
||||
|
||||
public String getRate() {
|
||||
return rate;
|
||||
}
|
||||
|
||||
public void setRate(String rate) {
|
||||
this.rate = rate;
|
||||
}
|
||||
|
||||
public int getSongId() {
|
||||
return songId;
|
||||
}
|
||||
|
||||
public void setSongId(int songId) {
|
||||
this.songId = songId;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class ChartPlay implements Serializable {
|
||||
private String songName;
|
||||
private String length;
|
||||
private String difficulty;
|
||||
private String chartZipUrl;
|
||||
private int likes;
|
||||
private int downloads;
|
||||
private String author;
|
||||
private int id;
|
||||
private boolean isUsed;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public boolean isUsed() {
|
||||
return isUsed;
|
||||
}
|
||||
|
||||
public void setUsed(boolean used) {
|
||||
isUsed = used;
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public String getSongName() {
|
||||
return songName;
|
||||
}
|
||||
|
||||
public void setSongName(String songName) {
|
||||
this.songName = songName;
|
||||
}
|
||||
|
||||
public String getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(String length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public String getDifficulty() {
|
||||
return difficulty;
|
||||
}
|
||||
|
||||
public void setDifficulty(String difficulty) {
|
||||
this.difficulty = difficulty;
|
||||
}
|
||||
|
||||
public String getChartZipUrl() {
|
||||
return chartZipUrl;
|
||||
}
|
||||
|
||||
public void setChartZipUrl(String chartZipUrl) {
|
||||
this.chartZipUrl = chartZipUrl;
|
||||
}
|
||||
|
||||
public int getLikes() {
|
||||
return likes;
|
||||
}
|
||||
|
||||
public void setLikes(int likes) {
|
||||
this.likes = likes;
|
||||
}
|
||||
|
||||
public int getDownloads() {
|
||||
return downloads;
|
||||
}
|
||||
|
||||
public void setDownloads(int downloads) {
|
||||
this.downloads = downloads;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.List;
|
||||
|
||||
public class Charts {
|
||||
@SerializedName("dx")
|
||||
private List<Chart> dx;
|
||||
@SerializedName("sd")
|
||||
private List<Chart> sd;
|
||||
|
||||
// Getters and Setters
|
||||
|
||||
public List<Chart> getDx() {
|
||||
return dx;
|
||||
}
|
||||
|
||||
public void setDx(List<Chart> dx) {
|
||||
this.dx = dx;
|
||||
}
|
||||
|
||||
public List<Chart> getSd() {
|
||||
return sd;
|
||||
}
|
||||
|
||||
public void setSd(List<Chart> sd) {
|
||||
this.sd = sd;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
public class ChatMessage {
|
||||
private String message;
|
||||
private String time;
|
||||
private boolean isUser;
|
||||
private boolean isThinking;
|
||||
|
||||
public ChatMessage(String message, boolean isUser) {
|
||||
this.message = message;
|
||||
this.isUser = isUser;
|
||||
this.isThinking = false;
|
||||
}
|
||||
public ChatMessage(String message, boolean isUser,String time) {
|
||||
this.message = message;
|
||||
this.isUser = isUser;
|
||||
this.isThinking = false;
|
||||
this.time = time;
|
||||
}
|
||||
public String getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(String time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public void setUser(boolean user) {
|
||||
isUser = user;
|
||||
}
|
||||
|
||||
public void setThinking(boolean thinking) {
|
||||
isThinking = thinking;
|
||||
}
|
||||
|
||||
public ChatMessage(String message, boolean isUser, boolean isThinking) {
|
||||
this.message = message;
|
||||
this.isUser = isUser;
|
||||
this.isThinking = isThinking;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public boolean isUser() {
|
||||
return isUser;
|
||||
}
|
||||
|
||||
public boolean isThinking() {
|
||||
return isThinking;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
public class CompassView extends View {
|
||||
private Paint paint;
|
||||
private float direction = 0.0f;
|
||||
|
||||
public CompassView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public CompassView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public CompassView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
paint = new Paint();
|
||||
paint.setColor(Color.RED);
|
||||
paint.setStrokeWidth(10);
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
}
|
||||
|
||||
public void setDirection(float direction) {
|
||||
this.direction = direction;
|
||||
invalidate(); // 重新绘制
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
int center = Math.min(width, height) / 2;
|
||||
|
||||
// 绘制指南针中心
|
||||
canvas.drawCircle(width / 2, height / 2, center, paint);
|
||||
|
||||
// 绘制指针
|
||||
float angle = (direction + 180) * (float) Math.PI / 180;
|
||||
float x = (float) (width / 2 + center * 0.8 * Math.cos(angle));
|
||||
float y = (float) (height / 2 + center * 0.8 * Math.sin(angle));
|
||||
|
||||
paint.setColor(Color.BLACK);
|
||||
paint.setStrokeWidth(5);
|
||||
canvas.drawLine(width / 2, height / 2, x, y, paint);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
|
||||
import org.astral.findmaimaiultra.been.lx.Notes;
|
||||
|
||||
public class Difficulty {
|
||||
private String type;
|
||||
private int difficulty;
|
||||
private String level;
|
||||
private double level_value;
|
||||
private String note_designer;
|
||||
private int version;
|
||||
private Notes notes;
|
||||
|
||||
// Getters and Setters
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getDifficulty() {
|
||||
return difficulty;
|
||||
}
|
||||
|
||||
public void setDifficulty(int difficulty) {
|
||||
this.difficulty = difficulty;
|
||||
}
|
||||
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(String level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public double getLevel_value() {
|
||||
return level_value;
|
||||
}
|
||||
|
||||
public void setLevel_value(double level_value) {
|
||||
this.level_value = level_value;
|
||||
}
|
||||
|
||||
public String getNote_designer() {
|
||||
return note_designer;
|
||||
}
|
||||
|
||||
public void setNote_designer(String note_designer) {
|
||||
this.note_designer = note_designer;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(int version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public Notes getNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
||||
public void setNotes(Notes notes) {
|
||||
this.notes = notes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
public class DistanceCalculator {
|
||||
|
||||
// 地球椭球参数(WGS-84)
|
||||
private static final double a = 6378137.0; // 长半轴
|
||||
private static final double b = 6356752.314245; // 短半轴
|
||||
private static final double f = 1 / 298.257223563; // 扁率
|
||||
|
||||
// 计算两点之间的距离
|
||||
public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
|
||||
// 将角度转换为弧度
|
||||
lat1 = Math.toRadians(lat1);
|
||||
lon1 = Math.toRadians(lon1);
|
||||
lat2 = Math.toRadians(lat2);
|
||||
lon2 = Math.toRadians(lon2);
|
||||
|
||||
// 计算纬度差和经度差
|
||||
double L = lon2 - lon1;
|
||||
double U1 = Math.atan((1 - f) * Math.tan(lat1));
|
||||
double U2 = Math.atan((1 - f) * Math.tan(lat2));
|
||||
|
||||
double sinU1 = Math.sin(U1);
|
||||
double cosU1 = Math.cos(U1);
|
||||
double sinU2 = Math.sin(U2);
|
||||
double cosU2 = Math.cos(U2);
|
||||
|
||||
double lambda = L;
|
||||
double lambdaP = 2 * Math.PI;
|
||||
double iterLimit = 20;
|
||||
|
||||
double cosSqAlpha = 0;
|
||||
double sinSigma = 0;
|
||||
double cosSigma = 0;
|
||||
double cos2SigmaM = 0;
|
||||
double sigma = 0;
|
||||
while (Math.abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0) {
|
||||
double sinLambda = Math.sin(lambda);
|
||||
double cosLambda = Math.cos(lambda);
|
||||
sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) +
|
||||
(cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda));
|
||||
if (sinSigma == 0) {
|
||||
return 0; // 两点重合
|
||||
}
|
||||
cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
|
||||
sigma = Math.atan2(sinSigma, cosSigma);
|
||||
double sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
|
||||
cosSqAlpha = 1 - sinAlpha * sinAlpha;
|
||||
cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
|
||||
if (Double.isNaN(cos2SigmaM)) {
|
||||
cos2SigmaM = 0; // 两点位于赤道上
|
||||
}
|
||||
double C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
|
||||
lambdaP = lambda;
|
||||
lambda = L + (1 - C) * f * sinAlpha *
|
||||
(sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
|
||||
}
|
||||
|
||||
if (iterLimit == 0) {
|
||||
return 0; // 迭代次数超过限制
|
||||
}
|
||||
|
||||
double uSq = cosSqAlpha * (a * a - b * b) / (b * b);
|
||||
double A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
|
||||
double B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
|
||||
double deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) -
|
||||
B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
|
||||
|
||||
double s = b * A * (sigma - deltaSigma);
|
||||
|
||||
return s / 1000; // 返回距离(单位:公里)
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
double lat1 = 39.9042; // 北京
|
||||
double lon1 = 116.4074;
|
||||
double lat2 = 31.2304; // 上海
|
||||
double lon2 = 121.4737;
|
||||
|
||||
double distance = calculateDistance(lat1, lon1, lat2, lon2);
|
||||
System.out.println("Distance between Beijing and Shanghai: " + distance + " km");
|
||||
}
|
||||
}
|
||||
125
app/src/main/java/org/astral/findmaimaiultra/been/Geocode.java
Normal file
@@ -0,0 +1,125 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
public class Geocode implements Parcelable {
|
||||
private String formatted_address;
|
||||
private String country;
|
||||
private String province;
|
||||
private String citycode;
|
||||
private String city;
|
||||
private String district;
|
||||
private String location;
|
||||
private String level;
|
||||
|
||||
public Geocode() {}
|
||||
|
||||
// 必须实现的构造函数,用于从Parcel中读取数据
|
||||
protected Geocode(Parcel in) {
|
||||
formatted_address = in.readString();
|
||||
country = in.readString();
|
||||
province = in.readString();
|
||||
citycode = in.readString();
|
||||
city = in.readString();
|
||||
district = in.readString();
|
||||
location = in.readString();
|
||||
level = in.readString();
|
||||
}
|
||||
|
||||
// 必须实现的方法,用于将对象写入Parcel
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(formatted_address);
|
||||
dest.writeString(country);
|
||||
dest.writeString(province);
|
||||
dest.writeString(citycode);
|
||||
dest.writeString(city);
|
||||
dest.writeString(district);
|
||||
dest.writeString(location);
|
||||
dest.writeString(level);
|
||||
}
|
||||
|
||||
// 必须实现的方法,返回一个CREATOR对象
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<Geocode> CREATOR = new Creator<Geocode>() {
|
||||
@Override
|
||||
public Geocode createFromParcel(Parcel in) {
|
||||
return new Geocode(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Geocode[] newArray(int size) {
|
||||
return new Geocode[size];
|
||||
}
|
||||
};
|
||||
|
||||
// Getter and Setter methods
|
||||
public void setFormatted_address(String formatted_address) {
|
||||
this.formatted_address = formatted_address;
|
||||
}
|
||||
|
||||
public String getFormatted_address() {
|
||||
return formatted_address;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setProvince(String province) {
|
||||
this.province = province;
|
||||
}
|
||||
|
||||
public String getProvince() {
|
||||
return province;
|
||||
}
|
||||
|
||||
public void setCitycode(String citycode) {
|
||||
this.citycode = citycode;
|
||||
}
|
||||
|
||||
public String getCitycode() {
|
||||
return citycode;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setDistrict(String district) {
|
||||
this.district = district;
|
||||
}
|
||||
|
||||
public String getDistrict() {
|
||||
return district;
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLevel(String level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
public class GpsData {
|
||||
private double x;
|
||||
private double y;
|
||||
private String key;
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
public class Market {
|
||||
private int id;
|
||||
private String marketName;
|
||||
private double distance;
|
||||
private int parentId;
|
||||
private double x;
|
||||
private double y;
|
||||
private int type;
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getMarketName() {
|
||||
return marketName;
|
||||
}
|
||||
|
||||
public void setMarketName(String marketName) {
|
||||
this.marketName = marketName;
|
||||
}
|
||||
|
||||
public double getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public void setDistance(double distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
|
||||
public int getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(int parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" +
|
||||
"\"id\":" + id +
|
||||
", \"marketName\":\"" + marketName + '\"' +
|
||||
", \"distance=\":" + distance +
|
||||
", \"parentId\":" + parentId +
|
||||
", \"x\":" + x +
|
||||
", \"y\":" + y +
|
||||
", \"type\":" + type +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
// Message.java
|
||||
public class Message {
|
||||
private String role;
|
||||
private String content;
|
||||
|
||||
public Message(String role, String content) {
|
||||
this.role = role;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
}
|
||||
214
app/src/main/java/org/astral/findmaimaiultra/been/Place.java
Normal file
@@ -0,0 +1,214 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class Place implements Parcelable {
|
||||
private int id;
|
||||
private String name;
|
||||
private String province;
|
||||
private String city;
|
||||
private String area;
|
||||
private String address;
|
||||
private int isUse;
|
||||
private double x;
|
||||
private double y;
|
||||
private int count;
|
||||
private int good;
|
||||
private int bad;
|
||||
public int num;
|
||||
public int numJ;
|
||||
private String meituan_link;
|
||||
private String douyin_link;
|
||||
|
||||
public String getMeituan_link() {
|
||||
return meituan_link;
|
||||
}
|
||||
|
||||
public void setMeituan_link(String meituan_link) {
|
||||
this.meituan_link = meituan_link;
|
||||
}
|
||||
|
||||
public String getDouyin_link() {
|
||||
return douyin_link;
|
||||
}
|
||||
|
||||
public void setDouyin_link(String douyin_link) {
|
||||
this.douyin_link = douyin_link;
|
||||
}
|
||||
|
||||
public int getNumJ() {
|
||||
return numJ;
|
||||
}
|
||||
|
||||
public void setNumJ(int numJ) {
|
||||
this.numJ = numJ;
|
||||
}
|
||||
|
||||
public Place(int id, String name, String province, String city, String area, String address, int isUse, double x, double y, int count, int good, int bad) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.province = province;
|
||||
this.city = city;
|
||||
this.area = area;
|
||||
this.address = address;
|
||||
this.isUse = isUse;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.count = count;
|
||||
this.good = good;
|
||||
this.bad = bad;
|
||||
}
|
||||
|
||||
protected Place(Parcel in) {
|
||||
id = in.readInt();
|
||||
name = in.readString();
|
||||
province = in.readString();
|
||||
city = in.readString();
|
||||
area = in.readString();
|
||||
address = in.readString();
|
||||
isUse = in.readInt();
|
||||
x = in.readDouble();
|
||||
y = in.readDouble();
|
||||
count = in.readInt();
|
||||
good = in.readInt();
|
||||
bad = in.readInt();
|
||||
}
|
||||
|
||||
public int getNum() {
|
||||
return num;
|
||||
}
|
||||
|
||||
public void setNum(int num) {
|
||||
this.num = num;
|
||||
}
|
||||
|
||||
public static final Creator<Place> CREATOR = new Creator<Place>() {
|
||||
@Override
|
||||
public Place createFromParcel(Parcel in) {
|
||||
return new Place(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Place[] newArray(int size) {
|
||||
return new Place[size];
|
||||
}
|
||||
};
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getProvince() {
|
||||
return province;
|
||||
}
|
||||
|
||||
public void setProvince(String province) {
|
||||
this.province = province;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getArea() {
|
||||
return area;
|
||||
}
|
||||
|
||||
public void setArea(String area) {
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public int getIsUse() {
|
||||
return isUse;
|
||||
}
|
||||
|
||||
public void setIsUse(int isUse) {
|
||||
this.isUse = isUse;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public int getGood() {
|
||||
return good;
|
||||
}
|
||||
|
||||
public void setGood(int good) {
|
||||
this.good = good;
|
||||
}
|
||||
|
||||
public int getBad() {
|
||||
return bad;
|
||||
}
|
||||
|
||||
public void setBad(int bad) {
|
||||
this.bad = bad;
|
||||
}
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(id);
|
||||
dest.writeString(name);
|
||||
dest.writeString(province);
|
||||
dest.writeString(city);
|
||||
dest.writeString(area);
|
||||
dest.writeString(address);
|
||||
dest.writeInt(isUse);
|
||||
dest.writeDouble(x);
|
||||
dest.writeDouble(y);
|
||||
dest.writeInt(count);
|
||||
dest.writeInt(good);
|
||||
dest.writeInt(bad);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
public class PlaceContent {
|
||||
private int id;
|
||||
private String user_name;
|
||||
private String user_content;
|
||||
private int place_id;
|
||||
private boolean used;
|
||||
|
||||
public boolean isUsed() {
|
||||
return used;
|
||||
}
|
||||
|
||||
public void setUsed(boolean used) {
|
||||
this.used = used;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUser_name() {
|
||||
return user_name;
|
||||
}
|
||||
|
||||
public void setUser_name(String user_name) {
|
||||
this.user_name = user_name;
|
||||
}
|
||||
|
||||
public String getUser_content() {
|
||||
return user_content;
|
||||
}
|
||||
|
||||
public void setUser_content(String user_content) {
|
||||
this.user_content = user_content;
|
||||
}
|
||||
|
||||
public int getPlace_id() {
|
||||
return place_id;
|
||||
}
|
||||
|
||||
public void setPlace_id(int place_id) {
|
||||
this.place_id = place_id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.List;
|
||||
|
||||
public class PlayerData {
|
||||
@SerializedName("additional_rating")
|
||||
private int additionalRating;
|
||||
@SerializedName("charts")
|
||||
private Charts charts;
|
||||
@SerializedName("nickname")
|
||||
private String nickname;
|
||||
@SerializedName("plate")
|
||||
private String plate;
|
||||
@SerializedName("rating")
|
||||
private int rating;
|
||||
@SerializedName("user_general_data")
|
||||
private Object userGeneralData;
|
||||
@SerializedName("username")
|
||||
private String username;
|
||||
|
||||
// Getters and Setters
|
||||
|
||||
public int getAdditionalRating() {
|
||||
return additionalRating;
|
||||
}
|
||||
|
||||
public void setAdditionalRating(int additionalRating) {
|
||||
this.additionalRating = additionalRating;
|
||||
}
|
||||
|
||||
public Charts getCharts() {
|
||||
return charts;
|
||||
}
|
||||
|
||||
public void setCharts(Charts charts) {
|
||||
this.charts = charts;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public String getPlate() {
|
||||
return plate;
|
||||
}
|
||||
|
||||
public void setPlate(String plate) {
|
||||
this.plate = plate;
|
||||
}
|
||||
|
||||
public int getRating() {
|
||||
return rating;
|
||||
}
|
||||
|
||||
public void setRating(int rating) {
|
||||
this.rating = rating;
|
||||
}
|
||||
|
||||
public Object getUserGeneralData() {
|
||||
return userGeneralData;
|
||||
}
|
||||
|
||||
public void setUserGeneralData(Object userGeneralData) {
|
||||
this.userGeneralData = userGeneralData;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Release {
|
||||
@SerializedName("tag_name")
|
||||
private String tagName;
|
||||
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
|
||||
@SerializedName("body")
|
||||
private String body;
|
||||
|
||||
@SerializedName("html_url")
|
||||
private String htmlUrl;
|
||||
|
||||
// Getters and setters
|
||||
public String getTagName() {
|
||||
return tagName;
|
||||
}
|
||||
|
||||
public void setTagName(String tagName) {
|
||||
this.tagName = tagName;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public String getHtmlUrl() {
|
||||
return htmlUrl;
|
||||
}
|
||||
|
||||
public void setHtmlUrl(String htmlUrl) {
|
||||
this.htmlUrl = htmlUrl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
// RequestData.java
|
||||
import java.util.List;
|
||||
|
||||
public class RequestData {
|
||||
private String model;
|
||||
private List<Message> messages;
|
||||
|
||||
public RequestData(String model, List<Message> messages) {
|
||||
this.model = model;
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public List<Message> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public void setMessages(List<Message> messages) {
|
||||
this.messages = messages;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.astral.findmaimaiultra.been;
|
||||
|
||||
// ResponseData.java
|
||||
public class ResponseData {
|
||||
private String model;
|
||||
private String created_at;
|
||||
private String response;
|
||||
private boolean done;
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public String getCreated_at() {
|
||||
return created_at;
|
||||
}
|
||||
|
||||
public void setCreated_at(String created_at) {
|
||||
this.created_at = created_at;
|
||||
}
|
||||
|
||||
public String getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
public void setResponse(String response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return done;
|
||||
}
|
||||
|
||||
public void setDone(boolean done) {
|
||||
this.done = done;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package org.astral.findmaimaiultra.been.faker;
|
||||
|
||||
public class MusicRating {
|
||||
private int musicId;
|
||||
private String musicName;
|
||||
|
||||
private int level;
|
||||
private double level_info;
|
||||
private int romVersion;
|
||||
private int achievement;
|
||||
private int rating;
|
||||
private String type;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getMusicName() {
|
||||
return musicName;
|
||||
}
|
||||
|
||||
public void setMusicName(String musicName) {
|
||||
this.musicName = musicName;
|
||||
}
|
||||
|
||||
public double getLevel_info() {
|
||||
return level_info;
|
||||
}
|
||||
|
||||
public void setLevel_info(double level_info) {
|
||||
this.level_info = level_info;
|
||||
}
|
||||
|
||||
public int getRating() {
|
||||
return rating;
|
||||
}
|
||||
|
||||
public void setRating(int rating) {
|
||||
this.rating = rating;
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public int getMusicId() {
|
||||
return musicId;
|
||||
}
|
||||
|
||||
public void setMusicId(int musicId) {
|
||||
this.musicId = musicId;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(int level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public int getRomVersion() {
|
||||
return romVersion;
|
||||
}
|
||||
|
||||
public void setRomVersion(int romVersion) {
|
||||
this.romVersion = romVersion;
|
||||
}
|
||||
|
||||
public int getAchievement() {
|
||||
return achievement;
|
||||
}
|
||||
|
||||
public void setAchievement(int achievement) {
|
||||
this.achievement = achievement;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.astral.findmaimaiultra.been.faker;
|
||||
|
||||
public class QRCodeMessage {
|
||||
private int errorID;
|
||||
private String key;
|
||||
private String timestamp;
|
||||
private int userID;
|
||||
|
||||
public int getErrorID() {
|
||||
return errorID;
|
||||
}
|
||||
|
||||
public void setErrorID(int errorID) {
|
||||
this.errorID = errorID;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(String timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public int getUserID() {
|
||||
return userID;
|
||||
}
|
||||
|
||||
public void setUserID(int userID) {
|
||||
this.userID = userID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.astral.findmaimaiultra.been.faker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RegionData {
|
||||
private int userId;
|
||||
private int length;
|
||||
private List<UserRegion> userRegionList;
|
||||
|
||||
public int getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(int userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(int length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public List<UserRegion> getUserRegionList() {
|
||||
return userRegionList;
|
||||
}
|
||||
|
||||
public void setUserRegionList(List<UserRegion> userRegionList) {
|
||||
this.userRegionList = userRegionList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package org.astral.findmaimaiultra.been.faker;
|
||||
|
||||
public class Udemae {
|
||||
private int maxLoseNum;
|
||||
private int npcTotalWinNum;
|
||||
private int npcTotalLoseNum;
|
||||
private int npcMaxWinNum;
|
||||
private int npcMaxLoseNum;
|
||||
private int npcWinNum;
|
||||
private int npcLoseNum;
|
||||
private int rate;
|
||||
private int classValue;
|
||||
private int maxRate;
|
||||
private int maxClassValue;
|
||||
private int totalWinNum;
|
||||
private int totalLoseNum;
|
||||
private int maxWinNum;
|
||||
private int MaxLoseNum;
|
||||
private int winNum;
|
||||
private int loseNum;
|
||||
private int NpcTotalWinNum;
|
||||
private int NpcTotalLoseNum;
|
||||
private int NpcMaxWinNum;
|
||||
private int NpcMaxLoseNum;
|
||||
private int NpcWinNum;
|
||||
private int NpcLoseNum;
|
||||
|
||||
// Getters and Setters
|
||||
|
||||
public int getMaxLoseNum() {
|
||||
return maxLoseNum;
|
||||
}
|
||||
|
||||
public void setMaxLoseNum(int maxLoseNum) {
|
||||
this.maxLoseNum = maxLoseNum;
|
||||
}
|
||||
|
||||
public int getWinNum() {
|
||||
return winNum;
|
||||
}
|
||||
|
||||
public void setWinNum(int winNum) {
|
||||
this.winNum = winNum;
|
||||
}
|
||||
|
||||
public int getLoseNum() {
|
||||
return loseNum;
|
||||
}
|
||||
|
||||
public void setLoseNum(int loseNum) {
|
||||
this.loseNum = loseNum;
|
||||
}
|
||||
|
||||
public int getNpcTotalWinNum() {
|
||||
return npcTotalWinNum;
|
||||
}
|
||||
|
||||
public void setNpcTotalWinNum(int npcTotalWinNum) {
|
||||
this.npcTotalWinNum = npcTotalWinNum;
|
||||
}
|
||||
|
||||
public int getNpcTotalLoseNum() {
|
||||
return npcTotalLoseNum;
|
||||
}
|
||||
|
||||
public void setNpcTotalLoseNum(int npcTotalLoseNum) {
|
||||
this.npcTotalLoseNum = npcTotalLoseNum;
|
||||
}
|
||||
|
||||
public int getNpcMaxWinNum() {
|
||||
return npcMaxWinNum;
|
||||
}
|
||||
|
||||
public void setNpcMaxWinNum(int npcMaxWinNum) {
|
||||
this.npcMaxWinNum = npcMaxWinNum;
|
||||
}
|
||||
|
||||
public int getNpcMaxLoseNum() {
|
||||
return npcMaxLoseNum;
|
||||
}
|
||||
|
||||
public void setNpcMaxLoseNum(int npcMaxLoseNum) {
|
||||
this.npcMaxLoseNum = npcMaxLoseNum;
|
||||
}
|
||||
|
||||
public int getNpcWinNum() {
|
||||
return npcWinNum;
|
||||
}
|
||||
|
||||
public void setNpcWinNum(int npcWinNum) {
|
||||
this.npcWinNum = npcWinNum;
|
||||
}
|
||||
|
||||
public int getNpcLoseNum() {
|
||||
return npcLoseNum;
|
||||
}
|
||||
|
||||
public void setNpcLoseNum(int npcLoseNum) {
|
||||
this.npcLoseNum = npcLoseNum;
|
||||
}
|
||||
|
||||
public int getRate() {
|
||||
return rate;
|
||||
}
|
||||
|
||||
public void setRate(int rate) {
|
||||
this.rate = rate;
|
||||
}
|
||||
|
||||
public int getClassValue() {
|
||||
return classValue;
|
||||
}
|
||||
|
||||
public void setClassValue(int classValue) {
|
||||
this.classValue = classValue;
|
||||
}
|
||||
|
||||
public int getMaxRate() {
|
||||
return maxRate;
|
||||
}
|
||||
|
||||
public void setMaxRate(int maxRate) {
|
||||
this.maxRate = maxRate;
|
||||
}
|
||||
|
||||
public int getMaxClassValue() {
|
||||
return maxClassValue;
|
||||
}
|
||||
|
||||
public void setMaxClassValue(int maxClassValue) {
|
||||
this.maxClassValue = maxClassValue;
|
||||
}
|
||||
|
||||
public int getTotalWinNum() {
|
||||
return totalWinNum;
|
||||
}
|
||||
|
||||
public void setTotalWinNum(int totalWinNum) {
|
||||
this.totalWinNum = totalWinNum;
|
||||
}
|
||||
|
||||
public int getTotalLoseNum() {
|
||||
return totalLoseNum;
|
||||
}
|
||||
|
||||
public void setTotalLoseNum(int totalLoseNum) {
|
||||
this.totalLoseNum = totalLoseNum;
|
||||
}
|
||||
|
||||
public int getMaxWinNum() {
|
||||
return maxWinNum;
|
||||
}
|
||||
|
||||
public void setMaxWinNum(int maxWinNum) {
|
||||
this.maxWinNum = maxWinNum;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
package org.astral.findmaimaiultra.been.faker;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class UserData {
|
||||
private int userId;
|
||||
private String userName;
|
||||
private boolean isLogin;
|
||||
private String lastGameId;
|
||||
private String lastRomVersion;
|
||||
private String lastDataVersion;
|
||||
private String lastLoginDate;
|
||||
private String lastPlayDate;
|
||||
private int playerRating;
|
||||
private int nameplateId;
|
||||
private int iconId;
|
||||
private int trophyId;
|
||||
private int isNetMember;
|
||||
private boolean isInherit;
|
||||
private int totalAwake;
|
||||
private int dispRate;
|
||||
private String dailyBonusDate;
|
||||
private String headPhoneVolume;
|
||||
private int banState;
|
||||
|
||||
public int getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(int userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public boolean isLogin() {
|
||||
return isLogin;
|
||||
}
|
||||
|
||||
public void setLogin(boolean login) {
|
||||
isLogin = login;
|
||||
}
|
||||
|
||||
public String getLastGameId() {
|
||||
return lastGameId;
|
||||
}
|
||||
|
||||
public void setLastGameId(String lastGameId) {
|
||||
this.lastGameId = lastGameId;
|
||||
}
|
||||
|
||||
public String getLastRomVersion() {
|
||||
return lastRomVersion;
|
||||
}
|
||||
|
||||
public void setLastRomVersion(String lastRomVersion) {
|
||||
this.lastRomVersion = lastRomVersion;
|
||||
}
|
||||
|
||||
public String getLastDataVersion() {
|
||||
return lastDataVersion;
|
||||
}
|
||||
|
||||
public void setLastDataVersion(String lastDataVersion) {
|
||||
this.lastDataVersion = lastDataVersion;
|
||||
}
|
||||
|
||||
public String getLastLoginDate() {
|
||||
return lastLoginDate;
|
||||
}
|
||||
|
||||
public void setLastLoginDate(String lastLoginDate) {
|
||||
this.lastLoginDate = lastLoginDate;
|
||||
}
|
||||
|
||||
public String getLastPlayDate() {
|
||||
return lastPlayDate;
|
||||
}
|
||||
|
||||
public void setLastPlayDate(String lastPlayDate) {
|
||||
this.lastPlayDate = lastPlayDate;
|
||||
}
|
||||
|
||||
public int getPlayerRating() {
|
||||
return playerRating;
|
||||
}
|
||||
|
||||
public void setPlayerRating(int playerRating) {
|
||||
this.playerRating = playerRating;
|
||||
}
|
||||
|
||||
public int getNameplateId() {
|
||||
return nameplateId;
|
||||
}
|
||||
|
||||
public void setNameplateId(int nameplateId) {
|
||||
this.nameplateId = nameplateId;
|
||||
}
|
||||
|
||||
public int getIconId() {
|
||||
return iconId;
|
||||
}
|
||||
|
||||
public void setIconId(int iconId) {
|
||||
this.iconId = iconId;
|
||||
}
|
||||
|
||||
public int getTrophyId() {
|
||||
return trophyId;
|
||||
}
|
||||
|
||||
public void setTrophyId(int trophyId) {
|
||||
this.trophyId = trophyId;
|
||||
}
|
||||
|
||||
public int getIsNetMember() {
|
||||
return isNetMember;
|
||||
}
|
||||
|
||||
public void setIsNetMember(int isNetMember) {
|
||||
this.isNetMember = isNetMember;
|
||||
}
|
||||
|
||||
public boolean isInherit() {
|
||||
return isInherit;
|
||||
}
|
||||
|
||||
public void setInherit(boolean inherit) {
|
||||
isInherit = inherit;
|
||||
}
|
||||
|
||||
public int getTotalAwake() {
|
||||
return totalAwake;
|
||||
}
|
||||
|
||||
public void setTotalAwake(int totalAwake) {
|
||||
this.totalAwake = totalAwake;
|
||||
}
|
||||
|
||||
public int getDispRate() {
|
||||
return dispRate;
|
||||
}
|
||||
|
||||
public void setDispRate(int dispRate) {
|
||||
this.dispRate = dispRate;
|
||||
}
|
||||
|
||||
public String getDailyBonusDate() {
|
||||
return dailyBonusDate;
|
||||
}
|
||||
|
||||
public void setDailyBonusDate(String dailyBonusDate) {
|
||||
this.dailyBonusDate = dailyBonusDate;
|
||||
}
|
||||
|
||||
public String getHeadPhoneVolume() {
|
||||
return headPhoneVolume;
|
||||
}
|
||||
|
||||
public void setHeadPhoneVolume(String headPhoneVolume) {
|
||||
this.headPhoneVolume = headPhoneVolume;
|
||||
}
|
||||
|
||||
public int getBanState() {
|
||||
return banState;
|
||||
}
|
||||
|
||||
public void setBanState(int banState) {
|
||||
this.banState = banState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package org.astral.findmaimaiultra.been.faker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserDataDetails {
|
||||
private String accessCode;
|
||||
private String userName;
|
||||
private String friendCode;
|
||||
private Integer isNetMember;
|
||||
private Integer playerRating;
|
||||
private Integer playerOldRating;
|
||||
private Integer playerNewRating;
|
||||
private Integer highestRating;
|
||||
private Integer gradeRating;
|
||||
private Integer musicRating;
|
||||
private Integer gradeRank;
|
||||
private Integer courseRank;
|
||||
private Integer classRank;
|
||||
private Integer nameplateId;
|
||||
private Integer frameId;
|
||||
private Integer iconId;
|
||||
private Integer trophyId;
|
||||
private Integer plateId;
|
||||
private Integer titleId;
|
||||
private Integer partnerId;
|
||||
private List<Integer> charaSlot;
|
||||
private List<Integer> charaLockSlot;
|
||||
private Long contentBit;
|
||||
private Integer selectMapId;
|
||||
private Integer playCount;
|
||||
private Integer currentPlayCount;
|
||||
private Integer playVsCount;
|
||||
private Integer playSyncCount;
|
||||
private Integer winCount;
|
||||
private Integer helpCount;
|
||||
private Integer comboCount;
|
||||
private Long totalDeluxscore;
|
||||
private Long totalBasicDeluxscore;
|
||||
private Long totalAdvancedDeluxscore;
|
||||
private Long totalExpertDeluxscore;
|
||||
private Long totalMasterDeluxscore;
|
||||
private Long totalReMasterDeluxscore;
|
||||
private Integer totalSync;
|
||||
private Integer totalBasicSync;
|
||||
private Integer totalAdvancedSync;
|
||||
private Integer totalExpertSync;
|
||||
private Integer totalMasterSync;
|
||||
private Integer totalReMasterSync;
|
||||
private Long totalAchievement;
|
||||
private Long totalBasicAchievement;
|
||||
private Long totalAdvancedAchievement;
|
||||
private Long totalExpertAchievement;
|
||||
private Long totalMasterAchievement;
|
||||
private Long totalReMasterAchievement;
|
||||
private String eventWatchedDate;
|
||||
private String lastGameId;
|
||||
private String lastRomVersion;
|
||||
private String lastDataVersion;
|
||||
private String lastLoginDate;
|
||||
private String lastPlayDate;
|
||||
private String lastPairLoginDate;
|
||||
private String lastTrialPlayDate;
|
||||
private Integer lastPlayCredit;
|
||||
private Integer lastPlayMode;
|
||||
private Integer lastPlaceId;
|
||||
private String lastPlaceName;
|
||||
private Integer lastAllNetId;
|
||||
private Integer lastRegionId;
|
||||
private String lastRegionName;
|
||||
private String lastClientId;
|
||||
private String lastCountryCode;
|
||||
private Integer lastSelectEMoney;
|
||||
private Integer lastSelectTicket;
|
||||
private Integer lastSelectCourse;
|
||||
private Integer lastCountCourse;
|
||||
private String firstGameId;
|
||||
private String firstRomVersion;
|
||||
private String firstDataVersion;
|
||||
private String firstPlayDate;
|
||||
private String compatibleCmVersion;
|
||||
private Integer totalAwake;
|
||||
private String dailyBonusDate;
|
||||
private String dailyCourseBonusDate;
|
||||
private Integer mapStock;
|
||||
private Integer renameCredit;
|
||||
private Integer cmLastEmoneyCredit;
|
||||
private Integer cmLastEmoneyBrand;
|
||||
private String dateTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.astral.findmaimaiultra.been.faker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserRating {
|
||||
private int rating;
|
||||
private List<MusicRating> ratingList;
|
||||
private List<MusicRating> newRatingList;
|
||||
private List<MusicRating> nextRatingList;
|
||||
private List<MusicRating> nextNewRatingList;
|
||||
private Udemae udemae;
|
||||
|
||||
// Getters and Setters
|
||||
public int getRating() {
|
||||
return rating;
|
||||
}
|
||||
|
||||
public void setRating(int rating) {
|
||||
this.rating = rating;
|
||||
}
|
||||
|
||||
public List<MusicRating> getRatingList() {
|
||||
return ratingList;
|
||||
}
|
||||
|
||||
public void setRatingList(List<MusicRating> ratingList) {
|
||||
this.ratingList = ratingList;
|
||||
}
|
||||
|
||||
public List<MusicRating> getNewRatingList() {
|
||||
return newRatingList;
|
||||
}
|
||||
|
||||
public void setNewRatingList(List<MusicRating> newRatingList) {
|
||||
this.newRatingList = newRatingList;
|
||||
}
|
||||
|
||||
public List<MusicRating> getNextRatingList() {
|
||||
return nextRatingList;
|
||||
}
|
||||
|
||||
public void setNextRatingList(List<MusicRating> nextRatingList) {
|
||||
this.nextRatingList = nextRatingList;
|
||||
}
|
||||
|
||||
public List<MusicRating> getNextNewRatingList() {
|
||||
return nextNewRatingList;
|
||||
}
|
||||
|
||||
public void setNextNewRatingList(List<MusicRating> nextNewRatingList) {
|
||||
this.nextNewRatingList = nextNewRatingList;
|
||||
}
|
||||
|
||||
public Udemae getUdemae() {
|
||||
return udemae;
|
||||
}
|
||||
|
||||
public void setUdemae(Udemae udemae) {
|
||||
this.udemae = udemae;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.astral.findmaimaiultra.been.faker;
|
||||
|
||||
public class UserRegion {
|
||||
private int regionId;
|
||||
private int playCount;
|
||||
private String province;
|
||||
private String created;
|
||||
|
||||
public String getProvince() {
|
||||
return province;
|
||||
}
|
||||
|
||||
public void setProvince(String province) {
|
||||
this.province = province;
|
||||
}
|
||||
|
||||
public int getRegionId() {
|
||||
return regionId;
|
||||
}
|
||||
|
||||
public void setRegionId(int regionId) {
|
||||
this.regionId = regionId;
|
||||
}
|
||||
|
||||
public int getPlayCount() {
|
||||
return playCount;
|
||||
}
|
||||
|
||||
public void setPlayCount(int playCount) {
|
||||
this.playCount = playCount;
|
||||
}
|
||||
|
||||
public String getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(String created) {
|
||||
this.created = created;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.astral.findmaimaiultra.been.faker;
|
||||
import java.util.List;
|
||||
|
||||
public class UserScore {
|
||||
private long userId;
|
||||
private UserRating userRating;
|
||||
|
||||
// Getters and Setters
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public UserRating getUserRating() {
|
||||
return userRating;
|
||||
}
|
||||
|
||||
public void setUserRating(UserRating userRating) {
|
||||
this.userRating = userRating;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.astral.findmaimaiultra.been.lx;
|
||||
|
||||
public class Difficulty {
|
||||
private String type;
|
||||
private int difficulty;
|
||||
private String level;
|
||||
private double level_value;
|
||||
private String note_designer;
|
||||
private int version;
|
||||
private Notes notes;
|
||||
|
||||
// Getters and Setters
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getDifficulty() {
|
||||
return difficulty;
|
||||
}
|
||||
|
||||
public void setDifficulty(int difficulty) {
|
||||
this.difficulty = difficulty;
|
||||
}
|
||||
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(String level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public double getLevel_value() {
|
||||
return level_value;
|
||||
}
|
||||
|
||||
public void setLevel_value(double level_value) {
|
||||
this.level_value = level_value;
|
||||
}
|
||||
|
||||
public String getNote_designer() {
|
||||
return note_designer;
|
||||
}
|
||||
|
||||
public void setNote_designer(String note_designer) {
|
||||
this.note_designer = note_designer;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(int version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public Notes getNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
||||
public void setNotes(Notes notes) {
|
||||
this.notes = notes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package org.astral.findmaimaiultra.been.lx;
|
||||
|
||||
public class Lx_chart {
|
||||
private int id;
|
||||
private String song_name;
|
||||
private String level;
|
||||
private int level_index;
|
||||
private double achievements;
|
||||
private String fc;
|
||||
private String fs;
|
||||
private int dx_score;
|
||||
private double dx_rating;
|
||||
private String rate;
|
||||
private String type;
|
||||
private String upload_time;
|
||||
|
||||
// 无参构造函数
|
||||
public Lx_chart() {}
|
||||
|
||||
// 全参构造函数
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getSong_name() {
|
||||
return song_name;
|
||||
}
|
||||
|
||||
public void setSong_name(String song_name) {
|
||||
this.song_name = song_name;
|
||||
}
|
||||
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(String level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public int getLevel_index() {
|
||||
return level_index;
|
||||
}
|
||||
|
||||
public void setLevel_index(int level_index) {
|
||||
this.level_index = level_index;
|
||||
}
|
||||
|
||||
public double getAchievements() {
|
||||
return achievements;
|
||||
}
|
||||
|
||||
public void setAchievements(double achievements) {
|
||||
this.achievements = achievements;
|
||||
}
|
||||
|
||||
public String getFc() {
|
||||
return fc;
|
||||
}
|
||||
|
||||
public void setFc(String fc) {
|
||||
this.fc = fc;
|
||||
}
|
||||
|
||||
public String getFs() {
|
||||
return fs;
|
||||
}
|
||||
|
||||
public void setFs(String fs) {
|
||||
this.fs = fs;
|
||||
}
|
||||
|
||||
public int getDx_score() {
|
||||
return dx_score;
|
||||
}
|
||||
|
||||
public void setDx_score(int dx_score) {
|
||||
this.dx_score = dx_score;
|
||||
}
|
||||
|
||||
public double getDx_rating() {
|
||||
return dx_rating;
|
||||
}
|
||||
|
||||
public void setDx_rating(double dx_rating) {
|
||||
this.dx_rating = dx_rating;
|
||||
}
|
||||
|
||||
public String getRate() {
|
||||
return rate;
|
||||
}
|
||||
|
||||
public void setRate(String rate) {
|
||||
this.rate = rate;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getUpload_time() {
|
||||
return upload_time;
|
||||
}
|
||||
|
||||
public void setUpload_time(String upload_time) {
|
||||
this.upload_time = upload_time;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.astral.findmaimaiultra.been.lx;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Lx_data {
|
||||
@SerializedName("standard_total")
|
||||
private int standardTotal;
|
||||
|
||||
@SerializedName("dx_total")
|
||||
private int dxTotal;
|
||||
|
||||
@SerializedName("standard")
|
||||
private List<Lx_chart> standard;
|
||||
|
||||
@SerializedName("dx")
|
||||
private List<Lx_chart> dx;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Lx_data{" +
|
||||
"standardTotal=" + standardTotal +
|
||||
", dxTotal=" + dxTotal +
|
||||
", standard=" + standard +
|
||||
", dx=" + dx +
|
||||
'}';
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public int getStandardTotal() {
|
||||
return standardTotal;
|
||||
}
|
||||
|
||||
public void setStandardTotal(int standardTotal) {
|
||||
this.standardTotal = standardTotal;
|
||||
}
|
||||
|
||||
public int getDxTotal() {
|
||||
return dxTotal;
|
||||
}
|
||||
|
||||
public void setDxTotal(int dxTotal) {
|
||||
this.dxTotal = dxTotal;
|
||||
}
|
||||
|
||||
public List<Lx_chart> getStandard() {
|
||||
return standard;
|
||||
}
|
||||
|
||||
public void setStandard(List<Lx_chart> standard) {
|
||||
this.standard = standard;
|
||||
}
|
||||
|
||||
public List<Lx_chart> getDx() {
|
||||
return dx;
|
||||
}
|
||||
|
||||
public void setDx(List<Lx_chart> dx) {
|
||||
this.dx = dx;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.astral.findmaimaiultra.been.lx;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Lx_data_scores {
|
||||
@SerializedName("success")
|
||||
private boolean success;
|
||||
|
||||
@SerializedName("code")
|
||||
private int code;
|
||||
|
||||
@SerializedName("data")
|
||||
private Lx_chart[] data;
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Lx_chart[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Lx_chart[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package org.astral.findmaimaiultra.been.lx;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Lx_playerInfo {
|
||||
@SerializedName("success")
|
||||
private boolean success;
|
||||
@SerializedName("code")
|
||||
private int code;
|
||||
@SerializedName("data")
|
||||
private Data data;
|
||||
|
||||
// Getters and Setters
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Data getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Data data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static class Data {
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("rating")
|
||||
private int rating;
|
||||
@SerializedName("friend_code")
|
||||
private long friendCode;
|
||||
@SerializedName("trophy")
|
||||
private Trophy trophy;
|
||||
@SerializedName("course_rank")
|
||||
private int courseRank;
|
||||
@SerializedName("class_rank")
|
||||
private int classRank;
|
||||
@SerializedName("star")
|
||||
private int star;
|
||||
@SerializedName("icon")
|
||||
private Icon icon;
|
||||
@SerializedName("upload_time")
|
||||
private String uploadTime;
|
||||
|
||||
// Getters and Setters
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getRating() {
|
||||
return rating;
|
||||
}
|
||||
|
||||
public void setRating(int rating) {
|
||||
this.rating = rating;
|
||||
}
|
||||
|
||||
public long getFriendCode() {
|
||||
return friendCode;
|
||||
}
|
||||
|
||||
public void setFriendCode(long friendCode) {
|
||||
this.friendCode = friendCode;
|
||||
}
|
||||
|
||||
public Trophy getTrophy() {
|
||||
return trophy;
|
||||
}
|
||||
|
||||
public void setTrophy(Trophy trophy) {
|
||||
this.trophy = trophy;
|
||||
}
|
||||
|
||||
public int getCourseRank() {
|
||||
return courseRank;
|
||||
}
|
||||
|
||||
public void setCourseRank(int courseRank) {
|
||||
this.courseRank = courseRank;
|
||||
}
|
||||
|
||||
public int getClassRank() {
|
||||
return classRank;
|
||||
}
|
||||
|
||||
public void setClassRank(int classRank) {
|
||||
this.classRank = classRank;
|
||||
}
|
||||
|
||||
public int getStar() {
|
||||
return star;
|
||||
}
|
||||
|
||||
public void setStar(int star) {
|
||||
this.star = star;
|
||||
}
|
||||
|
||||
public Icon getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public void setIcon(Icon icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public String getUploadTime() {
|
||||
return uploadTime;
|
||||
}
|
||||
|
||||
public void setUploadTime(String uploadTime) {
|
||||
this.uploadTime = uploadTime;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Trophy {
|
||||
@SerializedName("id")
|
||||
private int id;
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("color")
|
||||
private String color;
|
||||
|
||||
// Getters and Setters
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Icon {
|
||||
@SerializedName("id")
|
||||
private int id;
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("genre")
|
||||
private String genre;
|
||||
|
||||
// Getters and Setters
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getGenre() {
|
||||
return genre;
|
||||
}
|
||||
|
||||
public void setGenre(String genre) {
|
||||
this.genre = genre;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.astral.findmaimaiultra.been.lx;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Lx_res {
|
||||
@SerializedName("success")
|
||||
private boolean success;
|
||||
|
||||
@SerializedName("code")
|
||||
private int code;
|
||||
|
||||
@SerializedName("data")
|
||||
private Lx_data data;
|
||||
|
||||
// Getters and Setters
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Lx_data getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Lx_data data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package org.astral.findmaimaiultra.been.lx;
|
||||
|
||||
public class Notes {
|
||||
private int total;
|
||||
private int tap;
|
||||
private int hold;
|
||||
private int slide;
|
||||
private int touch;
|
||||
private int break_;
|
||||
|
||||
// Getters and Setters
|
||||
public int getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(int total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public int getTap() {
|
||||
return tap;
|
||||
}
|
||||
|
||||
public void setTap(int tap) {
|
||||
this.tap = tap;
|
||||
}
|
||||
|
||||
public int getHold() {
|
||||
return hold;
|
||||
}
|
||||
|
||||
public void setHold(int hold) {
|
||||
this.hold = hold;
|
||||
}
|
||||
|
||||
public int getSlide() {
|
||||
return slide;
|
||||
}
|
||||
|
||||
public void setSlide(int slide) {
|
||||
this.slide = slide;
|
||||
}
|
||||
|
||||
public int getTouch() {
|
||||
return touch;
|
||||
}
|
||||
|
||||
public void setTouch(int touch) {
|
||||
this.touch = touch;
|
||||
}
|
||||
|
||||
public int getBreak_() {
|
||||
return break_;
|
||||
}
|
||||
|
||||
public void setBreak_(int break_) {
|
||||
this.break_ = break_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package org.astral.findmaimaiultra.been.lx;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class Song {
|
||||
private int id;
|
||||
private String title;
|
||||
private String artist;
|
||||
private String genre;
|
||||
private int bpm;
|
||||
private int version;
|
||||
private String rights;
|
||||
private Map<String, Difficulty[]> difficulties;
|
||||
|
||||
// Getters and Setters
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getArtist() {
|
||||
return artist;
|
||||
}
|
||||
|
||||
public void setArtist(String artist) {
|
||||
this.artist = artist;
|
||||
}
|
||||
|
||||
public String getGenre() {
|
||||
return genre;
|
||||
}
|
||||
|
||||
public void setGenre(String genre) {
|
||||
this.genre = genre;
|
||||
}
|
||||
|
||||
public int getBpm() {
|
||||
return bpm;
|
||||
}
|
||||
|
||||
public void setBpm(int bpm) {
|
||||
this.bpm = bpm;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(int version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getRights() {
|
||||
return rights;
|
||||
}
|
||||
|
||||
public void setRights(String rights) {
|
||||
this.rights = rights;
|
||||
}
|
||||
|
||||
public Map<String, Difficulty[]> getDifficulties() {
|
||||
return difficulties;
|
||||
}
|
||||
|
||||
public void setDifficulties(Map<String, Difficulty[]> difficulties) {
|
||||
this.difficulties = difficulties;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package org.astral.findmaimaiultra.map2d;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import com.baidu.mapapi.SDKInitializer;
|
||||
import com.baidu.mapapi.map.*;
|
||||
import com.baidu.mapapi.model.LatLng;
|
||||
import org.astral.findmaimaiultra.R;
|
||||
import org.astral.findmaimaiultra.been.Place;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class BasicMapActivity extends AppCompatActivity {
|
||||
|
||||
private MapView mapView;
|
||||
private BaiduMap baiduMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
SDKInitializer.setAgreePrivacy(getApplicationContext(),true);
|
||||
SDKInitializer.initialize(getApplicationContext());
|
||||
setContentView(R.layout.maimaimap);
|
||||
|
||||
|
||||
Intent intent = getIntent();
|
||||
double x = Double.parseDouble(intent.getStringExtra("x"));
|
||||
double y = Double.parseDouble(intent.getStringExtra("y"));
|
||||
Log.d("BasicMapActivity", "x: " + x + ", y: " + y);
|
||||
mapView = findViewById(R.id.bmapView);
|
||||
mapView.onCreate(this,savedInstanceState);
|
||||
|
||||
baiduMap = mapView.getMap();
|
||||
|
||||
// 设置地图中心点
|
||||
LatLng latLng = new LatLng(y, x); // 北京市经纬度
|
||||
baiduMap.setMapStatus(MapStatusUpdateFactory.newLatLngZoom(latLng, 13)); // 缩放级别调整为
|
||||
|
||||
// 添加独特样式的标记
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo); // 自定义图标资源
|
||||
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, 200, 130, true); // 缩放到 100x100 像素
|
||||
BitmapDescriptor descriptor = BitmapDescriptorFactory.fromBitmap(scaledBitmap);
|
||||
MarkerOptions markerOptions = new MarkerOptions()
|
||||
.position(latLng)
|
||||
.title("舞萌痴位置")
|
||||
.icon(descriptor); // 使用自定义图标
|
||||
baiduMap.addOverlay(markerOptions);
|
||||
|
||||
ArrayList<Place> placeList = intent.getParcelableArrayListExtra("place_list_key");
|
||||
for (Place place : placeList) {
|
||||
addMarker(new LatLng(place.getY(), place.getX()), place.getName(), place.getAddress());
|
||||
}
|
||||
|
||||
// 设置标记点击监听器
|
||||
baiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
|
||||
@Override
|
||||
public boolean onMarkerClick(Marker marker) {
|
||||
showMarkerInfoDialog(marker);
|
||||
return true; // 返回 true 表示已处理点击事件
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 在 addMarker 方法中设置 snippet
|
||||
private void addMarker(LatLng latLng, String title, String snippet) {
|
||||
BitmapDescriptor descriptor = BitmapDescriptorFactory.fromResource(R.drawable.sd);
|
||||
MarkerOptions markerOptions = new MarkerOptions();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("snippet", snippet);
|
||||
bundle.putString("title", title);
|
||||
markerOptions.position(latLng)
|
||||
.title(title)
|
||||
.extraInfo(bundle)
|
||||
.icon(descriptor);
|
||||
baiduMap.addOverlay(markerOptions);
|
||||
}
|
||||
|
||||
// 在 showMarkerInfoDialog 方法中获取 snippet
|
||||
private void showMarkerInfoDialog(Marker marker) {
|
||||
View dialogView = LayoutInflater.from(this).inflate(R.layout.marker_info_dialog, null);
|
||||
TextView titleTextView = dialogView.findViewById(R.id.titleTextView);
|
||||
TextView snippetTextView = dialogView.findViewById(R.id.snippetTextView);
|
||||
Bundle extraInfo = marker.getExtraInfo();
|
||||
titleTextView.setText(extraInfo.getString("title"));
|
||||
// 获取 snippet
|
||||
snippetTextView.setText(extraInfo.getString("snippet"));
|
||||
|
||||
new AlertDialog.Builder(this)
|
||||
.setView(dialogView)
|
||||
.setPositiveButton("导航", new DialogInterface.OnClickListener(){
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
double lx = marker.getPosition().latitude;
|
||||
double ly = marker.getPosition().longitude;
|
||||
Intent intent = new Intent("android.intent.action.VIEW", android.net.Uri.parse("baidumap://map/direction?origin=latlng:" + lx + "," + ly + "|name:我的位置&destination=name:" + marker.getTitle() + "&mode=driving&src=yourCompanyName|yourAppName"));
|
||||
BasicMapActivity.this.startActivity(intent);
|
||||
}
|
||||
})
|
||||
.setNegativeButton("关闭", null)
|
||||
.show();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.astral.findmaimaiultra.message;
|
||||
|
||||
public class ApiResponse {
|
||||
private int status;
|
||||
private String message;
|
||||
private long timestamp;
|
||||
public ApiResponse() {
|
||||
}
|
||||
public ApiResponse(int status, String message) {
|
||||
this.status = status;
|
||||
this.message = message;
|
||||
this.timestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public ApiResponse(String uid) {
|
||||
this.status = 200;
|
||||
this.message = uid;
|
||||
this.timestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.astral.findmaimaiultra.service;
|
||||
|
||||
import org.astral.findmaimaiultra.been.Release;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Path;
|
||||
|
||||
public interface GitHubApiService {
|
||||
@GET("repos/{owner}/{repo}/releases/latest")
|
||||
Call<Release> getLatestRelease(@Path("owner") String owner, @Path("repo") String repo);
|
||||
}
|
||||
252
app/src/main/java/org/astral/findmaimaiultra/ui/LinkQQBot.java
Normal file
@@ -0,0 +1,252 @@
|
||||
// HackGetUserId.java
|
||||
package org.astral.findmaimaiultra.ui;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.TableRow;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
import com.google.gson.Gson;
|
||||
import okhttp3.*;
|
||||
import org.astral.findmaimaiultra.R;
|
||||
import org.astral.findmaimaiultra.been.faker.RegionData;
|
||||
import org.astral.findmaimaiultra.been.faker.UserRegion;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class LinkQQBot extends AppCompatActivity {
|
||||
private static Context context;
|
||||
private static final int REQUEST_IMAGE_PICK = 1;
|
||||
private TextInputEditText userId;
|
||||
private OkHttpClient client;
|
||||
private SharedPreferences sp;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_hack_get_user_id);
|
||||
context = this;
|
||||
sp = getSharedPreferences("setting", MODE_PRIVATE);
|
||||
userId = findViewById(R.id.userId);
|
||||
userId.setOnClickListener(v -> {
|
||||
Toast.makeText(this, "不可更改", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
userId.setText(sp.getString("userId", ""));
|
||||
if(sp.contains("userId")) {
|
||||
TextInputLayout userBox = findViewById(R.id.userBox);
|
||||
userBox.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
|
||||
|
||||
TextInputEditText key = findViewById(R.id.key);
|
||||
TextInputEditText safecode = findViewById(R.id.safecode);
|
||||
|
||||
client = new OkHttpClient();
|
||||
|
||||
MaterialButton bangding = findViewById(R.id.bangding);
|
||||
bangding.setOnClickListener(v -> {
|
||||
if (key.getText().toString().equals("")) {
|
||||
Toast.makeText(this, "请输入基于QQ机器人获取的Key", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
if (safecode.getText().toString().equals("")) {
|
||||
Toast.makeText(this, "请输入您的安全码", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
sendApiRequest(key.getText().toString(), safecode.getText().toString());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
MaterialButton getTicket = findViewById(R.id.getTicket);
|
||||
getTicket.setOnClickListener(v -> {
|
||||
try {
|
||||
getTicket(userId.getText().toString());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
// 如果已经保存了userId,则直接获取数据
|
||||
if (!userId.getText().toString().equals("")) {
|
||||
try {
|
||||
getUserRegionData(userId.getText().toString());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getTicket(String uid) throws Exception {
|
||||
String url = "http://mai.godserver.cn:11451/api/qq/wmcfajuan?qq=" + uid + "&num=6";
|
||||
Log.d("TAG", "getTicket: " + url);
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
|
||||
if (response.isSuccessful()) {
|
||||
runOnUiThread(() ->{
|
||||
try {
|
||||
Toast.makeText(LinkQQBot.this, response.body().string(), Toast.LENGTH_SHORT).show();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call call, @NonNull IOException e) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void sendApiRequest(String key,String safecode) throws Exception {
|
||||
String url = "http://mai.godserver.cn:11451/api/qq/safeCoding?result=" + key + "&safecode=" + safecode;
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
Log.d("TAG", "sendApiRequest: " + url);
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e) {
|
||||
e.printStackTrace();
|
||||
runOnUiThread(() -> Toast.makeText(LinkQQBot.this, "Request failed", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) throws IOException {
|
||||
if (response.isSuccessful()) {
|
||||
final String responseData = response.body().string();
|
||||
runOnUiThread(() -> {
|
||||
Toast.makeText(LinkQQBot.this, "Response: " + responseData, Toast.LENGTH_LONG).show();
|
||||
Log.d("TAG", "Response: " + responseData);
|
||||
userId.setText(responseData);
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
editor.putString("userId", responseData);
|
||||
editor.apply();
|
||||
Toast.makeText(LinkQQBot.this, "设置已保存,您的UsrId已写入硬盘!", Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
getUserRegionData(responseData);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
runOnUiThread(() -> Toast.makeText(LinkQQBot.this, "Request not successful", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void getUserRegionData(String userId) throws Exception {
|
||||
String url = "http://mai.godserver.cn:11451/api/qq/region2?qq=" + userId ;
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
Log.d("url",url);
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e) {
|
||||
e.printStackTrace();
|
||||
runOnUiThread(() -> Toast.makeText(LinkQQBot.this, "Request failed", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) throws IOException {
|
||||
if (response.isSuccessful()) {
|
||||
final String responseData = response.body().string();
|
||||
runOnUiThread(() -> {
|
||||
Log.d("TAG", "Response: " + responseData);
|
||||
Gson gson = new Gson();
|
||||
RegionData regionData = gson.fromJson(responseData, RegionData.class);
|
||||
sortUserRegions(regionData.getUserRegionList());
|
||||
});
|
||||
} else {
|
||||
runOnUiThread(() -> Toast.makeText(LinkQQBot.this, "Request not successful", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void sortUserRegions(List<UserRegion> userRegions) {
|
||||
Collections.sort(userRegions, new Comparator<UserRegion>() {
|
||||
@Override
|
||||
public int compare(UserRegion o1, UserRegion o2) {
|
||||
return Integer.compare(o2.getPlayCount(), o1.getPlayCount());
|
||||
}
|
||||
});
|
||||
// 处理排序后的数据,例如显示在表格中
|
||||
displaySortedUserRegions(userRegions);
|
||||
}
|
||||
|
||||
private void displaySortedUserRegions(List<UserRegion> userRegions) {
|
||||
// 假设你有一个TableLayout来显示数据
|
||||
TableLayout tableLayout = findViewById(R.id.tableLayout);
|
||||
tableLayout.removeAllViews();
|
||||
|
||||
// 添加表头
|
||||
TableRow headerRow = new TableRow(this);
|
||||
TextView headerRegionId = new TextView(this);
|
||||
headerRegionId.setText("地区 ID");
|
||||
TextView headerPlayCount = new TextView(this);
|
||||
headerPlayCount.setText("PC次数");
|
||||
TextView headerProvince = new TextView(this);
|
||||
headerProvince.setText("省份");
|
||||
TextView headerCreated = new TextView(this);
|
||||
headerCreated.setText("版本初次日期");
|
||||
headerCreated.setTextColor(ContextCompat.getColor(LinkQQBot.context, R.color.primary));
|
||||
headerRegionId.setTextColor(ContextCompat.getColor(LinkQQBot.context, R.color.primary));
|
||||
headerPlayCount.setTextColor(ContextCompat.getColor(LinkQQBot.context, R.color.primary));
|
||||
headerProvince.setTextColor(ContextCompat.getColor(LinkQQBot.context, R.color.primary));
|
||||
headerRow.addView(headerRegionId);
|
||||
headerRow.addView(headerPlayCount);
|
||||
headerRow.addView(headerProvince);
|
||||
headerRow.addView(headerCreated);
|
||||
tableLayout.addView(headerRow);
|
||||
|
||||
// 添加数据行
|
||||
for (UserRegion userRegion : userRegions) {
|
||||
TableRow row = new TableRow(this);
|
||||
TextView textViewRegionId = new TextView(this);
|
||||
textViewRegionId.setTextColor(ContextCompat.getColor(LinkQQBot.context, R.color.primary));
|
||||
textViewRegionId.setText(String.valueOf(userRegion.getRegionId()));
|
||||
TextView textViewPlayCount = new TextView(this);
|
||||
textViewPlayCount.setTextColor(ContextCompat.getColor(LinkQQBot.context, R.color.primary));
|
||||
textViewPlayCount.setText(String.valueOf(userRegion.getPlayCount()));
|
||||
TextView textViewProvince = new TextView(this);
|
||||
textViewProvince.setTextColor(ContextCompat.getColor(LinkQQBot.context, R.color.primary));
|
||||
textViewProvince.setText(userRegion.getProvince());
|
||||
TextView textViewCreated = new TextView(this);
|
||||
textViewCreated.setText(userRegion.getCreated());
|
||||
textViewCreated.setTextColor(ContextCompat.getColor(LinkQQBot.context, R.color.primary));
|
||||
row.addView(textViewRegionId);
|
||||
row.addView(textViewPlayCount);
|
||||
row.addView(textViewProvince);
|
||||
row.addView(textViewCreated);
|
||||
tableLayout.addView(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package org.astral.findmaimaiultra.ui;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.Menu;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.navigation.NavigationView;
|
||||
import androidx.navigation.NavController;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.navigation.ui.AppBarConfiguration;
|
||||
import androidx.navigation.ui.NavigationUI;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import org.astral.findmaimaiultra.R;
|
||||
import org.astral.findmaimaiultra.databinding.ActivityMainBinding;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private AppBarConfiguration mAppBarConfiguration;
|
||||
private ActivityMainBinding binding;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
setSupportActionBar(binding.appBarMain.toolbar);
|
||||
binding.appBarMain.fab.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
|
||||
.setAction("Action", null).show();
|
||||
}
|
||||
});
|
||||
DrawerLayout drawer = binding.drawerLayout;
|
||||
NavigationView navigationView = binding.navView;
|
||||
// Passing each menu ID as a set of Ids because each
|
||||
// menu should be considered as top level destinations.
|
||||
mAppBarConfiguration = new AppBarConfiguration.Builder(
|
||||
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow)
|
||||
.setOpenableLayout(drawer)
|
||||
.build();
|
||||
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
|
||||
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
|
||||
NavigationUI.setupWithNavController(navigationView, navController);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSupportNavigateUp() {
|
||||
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
|
||||
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|
||||
|| super.onSupportNavigateUp();
|
||||
}
|
||||
}
|
||||
1186
app/src/main/java/org/astral/findmaimaiultra/ui/PageActivity.java
Normal file
@@ -0,0 +1,157 @@
|
||||
package org.astral.findmaimaiultra.ui.gallery;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import com.baidu.mapapi.SDKInitializer;
|
||||
import com.baidu.mapapi.map.*;
|
||||
import com.baidu.mapapi.model.LatLng;
|
||||
import org.astral.findmaimaiultra.R;
|
||||
import org.astral.findmaimaiultra.been.Place;
|
||||
import org.astral.findmaimaiultra.databinding.FragmentGalleryBinding;
|
||||
import org.astral.findmaimaiultra.map2d.BasicMapActivity;
|
||||
import org.astral.findmaimaiultra.utill.SharedViewModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
|
||||
public class GalleryFragment extends Fragment {
|
||||
private FragmentGalleryBinding binding;
|
||||
private MapView mapView;
|
||||
private BaiduMap baiduMap;
|
||||
private SharedViewModel sharedViewModel;
|
||||
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
GalleryViewModel galleryViewModel =
|
||||
new ViewModelProvider(this).get(GalleryViewModel.class);
|
||||
SDKInitializer.setAgreePrivacy(requireContext().getApplicationContext(),true);
|
||||
SDKInitializer.initialize(requireContext().getApplicationContext());
|
||||
binding = FragmentGalleryBinding.inflate(inflater, container, false);
|
||||
View root = binding.getRoot();
|
||||
sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
|
||||
double x = Double.parseDouble(Objects.requireNonNull(sharedViewModel.getSharedMap().getValue().get("x")));
|
||||
double y = Double.parseDouble(Objects.requireNonNull(sharedViewModel.getSharedMap().getValue().get("y")));
|
||||
|
||||
mapView = binding.bmapView;
|
||||
mapView.onCreate(getContext(),savedInstanceState);
|
||||
|
||||
baiduMap = mapView.getMap();
|
||||
|
||||
// 设置地图中心点
|
||||
LatLng latLng = new LatLng(y, x); // 北京市经纬度
|
||||
baiduMap.setMapStatus(MapStatusUpdateFactory.newLatLngZoom(latLng, 13)); // 缩放级别调整为
|
||||
|
||||
// 添加独特样式的标记
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo); // 自定义图标资源
|
||||
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, 200, 130, true); // 缩放到 100x100 像素
|
||||
BitmapDescriptor descriptor = BitmapDescriptorFactory.fromBitmap(scaledBitmap);
|
||||
MarkerOptions markerOptions = new MarkerOptions()
|
||||
.position(latLng)
|
||||
.title("舞萌痴位置")
|
||||
.icon(descriptor); // 使用自定义图标
|
||||
baiduMap.addOverlay(markerOptions);
|
||||
|
||||
ArrayList<Place> placeList = Objects.requireNonNull(sharedViewModel.getPlacelist().getValue());
|
||||
for (Place place : placeList) {
|
||||
addMarker(new LatLng(place.getY(), place.getX()), place.getName(), place.getAddress());
|
||||
}
|
||||
|
||||
// 设置标记点击监听器
|
||||
baiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
|
||||
@Override
|
||||
public boolean onMarkerClick(Marker marker) {
|
||||
showMarkerInfoDialog(marker);
|
||||
return true; // 返回 true 表示已处理点击事件
|
||||
}
|
||||
});
|
||||
return root;
|
||||
}
|
||||
private void addMarker(LatLng latLng, String title, String snippet) {
|
||||
BitmapDescriptor descriptor = BitmapDescriptorFactory.fromResource(R.drawable.sd);
|
||||
MarkerOptions markerOptions = new MarkerOptions();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("snippet", snippet);
|
||||
bundle.putString("title", title);
|
||||
markerOptions.position(latLng)
|
||||
.title(title)
|
||||
.extraInfo(bundle)
|
||||
.icon(descriptor);
|
||||
baiduMap.addOverlay(markerOptions);
|
||||
}
|
||||
|
||||
// 在 showMarkerInfoDialog 方法中获取 snippet
|
||||
private void showMarkerInfoDialog(Marker marker) {
|
||||
View dialogView = LayoutInflater.from(getContext()).inflate(R.layout.marker_info_dialog, null);
|
||||
TextView titleTextView = dialogView.findViewById(R.id.titleTextView);
|
||||
TextView snippetTextView = dialogView.findViewById(R.id.snippetTextView);
|
||||
Bundle extraInfo = marker.getExtraInfo();
|
||||
try {
|
||||
titleTextView.setText(extraInfo.getString("title"));
|
||||
// 获取 snippet
|
||||
snippetTextView.setText(extraInfo.getString("snippet"));
|
||||
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setView(dialogView)
|
||||
.setPositiveButton("导航", new DialogInterface.OnClickListener(){
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
double lx = marker.getPosition().latitude;
|
||||
double ly = marker.getPosition().longitude;
|
||||
Intent intent = new Intent("android.intent.action.VIEW", android.net.Uri.parse("baidumap://map/direction?origin=latlng:" + lx + "," + ly + "|name:我的位置&destination=name:" + marker.getTitle() + "&mode=driving&src=yourCompanyName|yourAppName"));
|
||||
getContext().startActivity(intent);
|
||||
}
|
||||
})
|
||||
.setNegativeButton("关闭", null)
|
||||
.show();
|
||||
}catch (Exception e) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(getContext(), "乌蒙痴位置", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.astral.findmaimaiultra.ui.gallery;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
public class GalleryViewModel extends ViewModel {
|
||||
|
||||
private final MutableLiveData<String> mText;
|
||||
|
||||
public GalleryViewModel() {
|
||||
mText = new MutableLiveData<>();
|
||||
mText.setValue("This is gallery fragment");
|
||||
}
|
||||
|
||||
public LiveData<String> getText() {
|
||||
return mText;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,567 @@
|
||||
package org.astral.findmaimaiultra.ui.home;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.*;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.location.Address;
|
||||
import android.location.Geocoder;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.GravityCompat;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.navigation.NavigationView;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import okhttp3.*;
|
||||
import org.astral.findmaimaiultra.R;
|
||||
import org.astral.findmaimaiultra.adapter.PlaceAdapter;
|
||||
import org.astral.findmaimaiultra.been.*;
|
||||
import org.astral.findmaimaiultra.databinding.FragmentHomeBinding;
|
||||
import org.astral.findmaimaiultra.ui.MainActivity;
|
||||
import org.astral.findmaimaiultra.ui.PageActivity;
|
||||
import org.astral.findmaimaiultra.utill.AddressParser;
|
||||
import org.astral.findmaimaiultra.utill.SharedViewModel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.*;
|
||||
|
||||
public class HomeFragment extends Fragment {
|
||||
private RecyclerView recyclerView;
|
||||
private Handler handler = new Handler(Looper.getMainLooper());
|
||||
private LocationManager locationManager;
|
||||
private String tot;
|
||||
private String x;
|
||||
private String y;
|
||||
private PlaceAdapter adapter;
|
||||
public static List<Market> marketList = new ArrayList<>();
|
||||
private Context context;
|
||||
public static String province;
|
||||
public static String city;
|
||||
public static List<Place> a = new ArrayList<>();
|
||||
public static List<Place> b = new ArrayList<>();
|
||||
private BroadcastReceiver locationReceiver;
|
||||
public static List<TextView> textViews = new ArrayList<>();
|
||||
private boolean flag = true;
|
||||
private double tagXY[] = new double[2];
|
||||
private String tagplace;
|
||||
private boolean isFlag = true;
|
||||
private SharedPreferences shoucang;
|
||||
private SharedPreferences settingProperties;
|
||||
private FragmentHomeBinding binding;
|
||||
private SharedViewModel sharedViewModel;
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
// 获取 SharedPreferences 实例
|
||||
context = getContext();
|
||||
if (context != null) {
|
||||
shoucang = context.getSharedPreferences("shoucang_prefs", Context.MODE_PRIVATE);
|
||||
settingProperties = context.getSharedPreferences("setting_prefs", Context.MODE_PRIVATE);
|
||||
}
|
||||
sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
HomeViewModel homeViewModel =
|
||||
new ViewModelProvider(this).get(HomeViewModel.class);
|
||||
|
||||
binding = FragmentHomeBinding.inflate(inflater, container, false);
|
||||
View root = binding.getRoot();
|
||||
recyclerView = binding.recyclerView;
|
||||
|
||||
// 初始化 RecyclerView
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
|
||||
// 初始化数据
|
||||
List<Place> placeList = new ArrayList<>();
|
||||
recyclerView.setAdapter(adapter);
|
||||
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},0x123);
|
||||
|
||||
// 示例:读取 SharedPreferences 中的数据
|
||||
if (shoucang != null) {
|
||||
String savedData = shoucang.getString("key_name", "default_value");
|
||||
// 使用 savedData
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
binding = null;
|
||||
}
|
||||
|
||||
// 示例:写入 SharedPreferences 数据
|
||||
private void saveDataToSharedPreferences(String key, String value) {
|
||||
if (shoucang != null) {
|
||||
SharedPreferences.Editor editor = shoucang.edit();
|
||||
editor.putString(key, value);
|
||||
editor.apply(); // 或者 editor.commit();
|
||||
}
|
||||
}
|
||||
private void showNetworkErrorToast(String text) {
|
||||
if (getActivity() != null) {
|
||||
getActivity().runOnUiThread(() -> Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private void sendGetRequest() {
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
|
||||
String web = "http://mai.godserver.cn:11451/api/mai/v1/search?prompt1=" + city.split("市")[0] + "&status=市";
|
||||
if (!isFlag) {
|
||||
web = "http://mai.godserver.cn:11451/api/mai/v1/search?data_place=" + tagplace;
|
||||
}
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(web)
|
||||
.build();
|
||||
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e) {
|
||||
Log.e("OkHttp", "Error: " + e.getMessage());
|
||||
showNetworkErrorToast("网络错误");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) throws IOException {
|
||||
if (response.isSuccessful()) {
|
||||
String result = response.body().string();
|
||||
if (!result.equals("BedWeb")) {
|
||||
List<Place> places = parseJsonToPlaceList(result);
|
||||
if (places != null) {
|
||||
updateUI(places);
|
||||
}
|
||||
} else {
|
||||
showNetworkErrorToast("网络错误(服务器维护)");
|
||||
}
|
||||
} else {
|
||||
showNetworkErrorToast( "致命错误,服务器未启动");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateUI(List<Place> places) {
|
||||
a.clear();
|
||||
b.clear();
|
||||
|
||||
for (Place p : places) {
|
||||
try {
|
||||
if (p.getName().equals("个人位置")) {
|
||||
x = String.valueOf(p.getX());
|
||||
y = String.valueOf(p.getY());
|
||||
tot = p.getAddress();
|
||||
city = p.getCity();
|
||||
province = p.getProvince();
|
||||
}
|
||||
if (p.getIsUse() == 1) {
|
||||
b.add(p);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
a.clear();
|
||||
TreeMap<Double, Place> treeMap = new TreeMap<>();
|
||||
|
||||
for (Place p : b) {
|
||||
double distance = DistanceCalculator.calculateDistance(Double.parseDouble(x), Double.parseDouble(y), p.getX(), p.getY());
|
||||
|
||||
if (shoucang.contains(p.getId() + "")) {
|
||||
p.setName(p.getName() + " 收藏" + " 距离您" + String.format(Locale.CHINA, "%.2f", distance) + "km");
|
||||
treeMap.put(distance - 1000, p);
|
||||
} else {
|
||||
p.setName(p.getName() + " 距离您" + String.format(Locale.CHINA, "%.2f", distance) + "km");
|
||||
treeMap.put(distance, p);
|
||||
}
|
||||
if (p.getNumJ() > 0) {
|
||||
p.setName(p.getName() + "\uD83D\uDCB3");
|
||||
}
|
||||
}
|
||||
|
||||
for (Double key : treeMap.keySet()) {
|
||||
a.add(treeMap.get(key));
|
||||
}
|
||||
|
||||
boolean flag2 = true;
|
||||
if (flag2) {
|
||||
adapter = new PlaceAdapter(a, new PlaceAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(Place place) {
|
||||
Intent intent = new Intent(context, PageActivity.class);
|
||||
intent.putExtra("id", place.getId());
|
||||
intent.putExtra("name", place.getName());
|
||||
intent.putExtra("address", place.getAddress());
|
||||
intent.putExtra("province", place.getProvince());
|
||||
intent.putExtra("city", place.getCity());
|
||||
intent.putExtra("area", place.getArea());
|
||||
intent.putExtra("x", place.getX());
|
||||
intent.putExtra("y", place.getY());
|
||||
intent.putExtra("count", place.getCount());
|
||||
intent.putExtra("bad", place.getBad());
|
||||
intent.putExtra("good", place.getGood());
|
||||
intent.putExtra("num", place.getNum());
|
||||
intent.putExtra("numJ", place.getNumJ());
|
||||
intent.putExtra("meituan", place.getMeituan_link());
|
||||
intent.putExtra("douyin", place.getDouyin_link());
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
recyclerView.setAdapter(adapter);
|
||||
// 设置 Toolbar 标题
|
||||
String navHomeLabel = getString(R.string.menu_home);
|
||||
Toolbar toolbar = ((MainActivity) requireActivity()).findViewById(R.id.toolbar);
|
||||
toolbar.setTitle("FindMaimaiDX - " + a.size() + " 店铺" + "\n" + tot);
|
||||
|
||||
// 更新 SharedViewModel 中的 Map
|
||||
sharedViewModel.addToMap("places", new Gson().toJson(a));
|
||||
|
||||
// 通知适配器数据已更改
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
// 设置Toolbar
|
||||
|
||||
for (Place p : a) {
|
||||
if (p.getX() == 0.0) {
|
||||
// Log.i(p.getId() + "", p.getName() + "没有坐标");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Place> parseJsonToPlaceList(String jsonString) {
|
||||
Gson gson = new Gson();
|
||||
Type placeListType = new TypeToken<List<Place>>() {
|
||||
}.getType();
|
||||
if(jsonString.equals("BedWeb")) {
|
||||
Toast.makeText(context, "网络错误(服务器维护?)", Toast.LENGTH_SHORT);
|
||||
return null;
|
||||
}
|
||||
return gson.fromJson(jsonString, placeListType);
|
||||
}
|
||||
@SuppressLint("MissingPermission")
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == 0x123 && grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
// 创建 LocationManager 对象
|
||||
locationManager = (LocationManager) requireActivity().getSystemService(Context.LOCATION_SERVICE);
|
||||
// 获取最新的定位信息
|
||||
Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
|
||||
if (lastKnownLocation != null) {
|
||||
// 调用高德地图 API 进行逆地理编码
|
||||
reverseGeocode(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude());
|
||||
} else {
|
||||
Log.d("Location", "无法获取最新定位信息");
|
||||
setDefaultLocation(); // 设置默认位置
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 12000, 16f, new LocationListener() {
|
||||
@Override
|
||||
public void onLocationChanged(@NonNull Location location) {
|
||||
Log.d("Location", "onLocationChanged");
|
||||
if (flag) {
|
||||
Toast.makeText(context, "定位成功", Toast.LENGTH_SHORT).show();
|
||||
// 调用高德地图 API 进行逆地理编码
|
||||
reverseGeocode(location.getLatitude(), location.getLongitude());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(@NonNull String provider) {
|
||||
Toast.makeText(requireActivity().getApplicationContext(), "关闭定位", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.d("Location", "GPS定位失败");
|
||||
setDefaultLocation(); // 设置默认位置
|
||||
}
|
||||
}
|
||||
|
||||
// 调用高德地图 API 进行逆地理编码
|
||||
private void reverseGeocode(double latitude, double longitude) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
// 构建请求 URL
|
||||
x = String.valueOf(longitude);
|
||||
y = String.valueOf(latitude);
|
||||
String url = "https://restapi.amap.com/v3/geocode/regeo?key=234cad2e2f0706e54c92591647a363c3&location=" + longitude + "," + latitude;
|
||||
Log.d("Location", url);
|
||||
// 发起网络请求
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
Request request = new Request.Builder().url(url).build();
|
||||
Response response = client.newCall(request).execute();
|
||||
if (response.isSuccessful()) {
|
||||
String responseData = response.body().string();
|
||||
// 使用 Gson 解析 JSON
|
||||
Gson gson = new Gson();
|
||||
Log.d("Location", responseData);
|
||||
AmapReverseGeocodeResponse geocodeResponse = gson.fromJson(responseData, AmapReverseGeocodeResponse.class);
|
||||
if (geocodeResponse.getStatus().equals("1")) { // 状态码 "1" 表示成功
|
||||
AmapReverseGeocodeResponse.Regeocode regeocode = geocodeResponse.getRegeocode();
|
||||
AmapReverseGeocodeResponse.AddressComponent addressComponent = regeocode.getAddressComponent();
|
||||
// 解析地址信息
|
||||
String address = regeocode.getFormattedAddress();
|
||||
String province = addressComponent.getProvince();
|
||||
String city;
|
||||
try {
|
||||
city = addressComponent.getCity().get(0).replace("市", "");
|
||||
} catch (Exception e) {
|
||||
city = addressComponent.getProvince().replace("市", "");
|
||||
}
|
||||
// 更新 UI
|
||||
String finalCity = city;
|
||||
getActivity().runOnUiThread(() -> {
|
||||
tot = address;
|
||||
HomeFragment.province = province;
|
||||
HomeFragment.city = finalCity;
|
||||
sharedViewModel.addToMap("tot", tot);
|
||||
sharedViewModel.addToMap("x", x);
|
||||
sharedViewModel.addToMap("y", y);
|
||||
extracted();
|
||||
});
|
||||
} else {
|
||||
Log.d("Location", "高德地图 API 调用失败,尝试使用 Android 自带 Geocoder");
|
||||
fallbackToGeocoder(latitude, longitude); // 调用备用方案
|
||||
}
|
||||
} else {
|
||||
Log.d("Location", "高德地图 API 调用失败,尝试使用 Android 自带 Geocoder");
|
||||
fallbackToGeocoder(latitude, longitude); // 调用备用方案
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.d("Location", "高德地图 API 调用失败,尝试使用 Android 自带 Geocoder");
|
||||
fallbackToGeocoder(latitude, longitude); // 调用备用方案
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
// 备用方案:使用 Android 自带的 Geocoder 进行逆地理编码
|
||||
private void fallbackToGeocoder(double latitude, double longitude) {
|
||||
try {
|
||||
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
|
||||
List<android.location.Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
|
||||
if (addresses != null && !addresses.isEmpty()) {
|
||||
Address address = addresses.get(0);
|
||||
String detail = address.getAddressLine(0);
|
||||
String province = address.getAdminArea();
|
||||
String city = address.getLocality();
|
||||
// 更新 UI
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
tot = detail;
|
||||
this.province = province;
|
||||
this.city = city;
|
||||
extracted();
|
||||
});
|
||||
} else {
|
||||
Log.d("Location", "Android 自带 Geocoder 获取地址失败");
|
||||
setDefaultLocation(); // 设置默认位置
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Log.d("Location", "Android 自带 Geocoder 获取地址失败");
|
||||
setDefaultLocation(); // 设置默认位置
|
||||
}
|
||||
}
|
||||
|
||||
// 设置默认位置
|
||||
private void setDefaultLocation() {
|
||||
x = String.valueOf(116.3912757);
|
||||
y = String.valueOf(39.906217);
|
||||
}
|
||||
|
||||
//手动刷新定位
|
||||
private void extracted() {
|
||||
//tot = tot.split("\"")[1];
|
||||
Log.i("TAG", "x=" + x + ";y=" + y);
|
||||
//tot = "天津市东丽区民航大学";
|
||||
if(!isFlag) {
|
||||
|
||||
}else {
|
||||
try {
|
||||
AddressParser.parseAddress(tot);
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(context, "错误", Toast.LENGTH_SHORT);
|
||||
|
||||
}
|
||||
}
|
||||
sendGetRequest();
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(context));
|
||||
|
||||
}
|
||||
public static List<Geocode> parseJsonToGeocodeList(String jsonString) {
|
||||
Gson gson = new Gson();
|
||||
JsonArray jsonArray = gson.fromJson(jsonString, JsonArray.class);
|
||||
List<Geocode> Geocodes = new ArrayList<>();
|
||||
for (JsonElement jsonElement : jsonArray) {
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
Geocode geocode = new Geocode();
|
||||
// 获取 marketName
|
||||
String formatted_address = jsonObject.get("formatted_address").getAsString();
|
||||
geocode.setFormatted_address(formatted_address);
|
||||
geocode.setProvince(jsonObject.get("province").getAsString());
|
||||
geocode.setCity(jsonObject.get("city").getAsString());
|
||||
geocode.setDistrict(jsonObject.get("district").getAsString());
|
||||
geocode.setCountry(jsonObject.get("country").getAsString());
|
||||
geocode.setLevel(jsonObject.get("level").getAsString());
|
||||
geocode.setCitycode(jsonObject.get("citycode").getAsString());
|
||||
// 获取 x, y
|
||||
String location = jsonObject.get("location").getAsString();
|
||||
String[] coordinates = location.split(",");
|
||||
geocode.setLocation(location);
|
||||
Geocodes.add(geocode);
|
||||
}
|
||||
return Geocodes;
|
||||
}
|
||||
private String getAppVersionName() {
|
||||
try {
|
||||
PackageInfo packageInfo = requireActivity().getPackageManager().getPackageInfo(requireActivity().getPackageName(), 0);
|
||||
return packageInfo.versionName;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开QQ
|
||||
* @param context
|
||||
*/
|
||||
public static void gotoQQ(Context context) {
|
||||
try {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_MAIN);
|
||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.setComponent(new ComponentName("com.tencent.mobileqq", "com.tencent.mobileqq.activity.SplashActivity"));
|
||||
if (!(context instanceof Activity)) {
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
context.startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(context, "未安装QQ", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void addPlace(Place place) {
|
||||
String url = "http://mai.godserver.cn:11451/api/mai/v1/place";
|
||||
String body = new Gson().toJson(place,Place.class);
|
||||
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), body);
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.put(requestBody)
|
||||
.build();
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e) {
|
||||
Toast.makeText(context, "添加失败", Toast.LENGTH_SHORT).show();
|
||||
e.printStackTrace();
|
||||
}
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) throws IOException {
|
||||
if (response.isSuccessful()) {
|
||||
final String responseData = response.body().string();
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
Toast.makeText(context, "添加成功", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}else {
|
||||
Toast.makeText(context, "添加失败", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
private void showNavigationOptions() {
|
||||
final CharSequence[] items = {"Google Maps", "高德地图", "百度地图(暂时不可用)"};
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
builder.setTitle("选择导航应用")
|
||||
.setItems(items, (dialog, item) -> {
|
||||
switch (item) {
|
||||
case 0:
|
||||
startGoogleMaps();
|
||||
break;
|
||||
case 1:
|
||||
startAmap();
|
||||
break;
|
||||
case 2:
|
||||
startBaiduMaps();
|
||||
break;
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
private void startGoogleMaps() {
|
||||
String uri = "google.navigation:q=" + tagXY[0] + "," + tagXY[1];
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
||||
intent.setPackage("com.google.android.apps.maps");
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
private void startAmap() {
|
||||
// 高德地图
|
||||
Intent intent = new Intent("android.intent.action.VIEW", android.net.Uri.parse("androidamap://route?sourceApplication=appName&slat=&slon=&sname=我的位置&dlat=" + tagXY[1] +"&dlon="+ tagXY[0]+"&dname=" +tagplace + "&dev=0&t=2"));
|
||||
this.startActivity(intent);
|
||||
}
|
||||
|
||||
private void startBaiduMaps() {
|
||||
Toast.makeText(PageActivity.context, "111", Toast.LENGTH_SHORT).show();
|
||||
String uri = "baidumap://map/direction?destination=latlng:" + tagXY[0] + "," + tagXY[1] +"&mode=driving&src=appName";
|
||||
Intent intent = new Intent("com.baidu.tieba", android.net.Uri.parse(uri));
|
||||
startActivity(intent);
|
||||
}
|
||||
private static List<Market> parseJsonToPlaceList2(String jsonString) {
|
||||
Gson gson = new Gson();
|
||||
Type placeListType = new TypeToken<List<Market>>() {
|
||||
}.getType();
|
||||
return gson.fromJson(jsonString, placeListType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.astral.findmaimaiultra.ui.home;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
public class HomeViewModel extends ViewModel {
|
||||
|
||||
private final MutableLiveData<String> mText;
|
||||
|
||||
public HomeViewModel() {
|
||||
mText = new MutableLiveData<>();
|
||||
mText.setValue("This is home fragment");
|
||||
}
|
||||
|
||||
public LiveData<String> getText() {
|
||||
return mText;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
package org.astral.findmaimaiultra.ui.slideshow;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.*;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.Settings;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.radiobutton.MaterialRadioButton;
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.yalantis.ucrop.UCrop;
|
||||
import org.astral.findmaimaiultra.been.Release;
|
||||
import org.astral.findmaimaiultra.databinding.FragmentSlideshowBinding;
|
||||
import org.astral.findmaimaiultra.service.GitHubApiService;
|
||||
import org.astral.findmaimaiultra.ui.LinkQQBot;
|
||||
import org.astral.findmaimaiultra.utill.GitHubApiClient;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.Objects;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
public class SlideshowFragment extends Fragment {
|
||||
private SharedPreferences settingProperties;
|
||||
private static final int PICK_IMAGE_REQUEST = 1;
|
||||
private static final int REQUEST_CODE_PERMISSIONS = 1001;
|
||||
private TextInputEditText shuiyuEditText;
|
||||
private TextInputEditText luoxueEditText;
|
||||
private TextInputEditText userId;
|
||||
private String x;
|
||||
private String y;
|
||||
private FragmentSlideshowBinding binding;
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
settingProperties = requireActivity().getSharedPreferences("setting", Context.MODE_PRIVATE);
|
||||
}
|
||||
private void show(String text) {
|
||||
if (getActivity() != null) {
|
||||
getActivity().runOnUiThread(() -> Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
SlideshowViewModel slideshowViewModel =
|
||||
new ViewModelProvider(this).get(SlideshowViewModel.class);
|
||||
|
||||
binding = FragmentSlideshowBinding.inflate(inflater, container, false);
|
||||
View root = binding.getRoot();
|
||||
SwitchMaterial switchMaterial = binding.switchBeta1;
|
||||
switchMaterial.setChecked(settingProperties.getBoolean("setting_autobeta1", false));
|
||||
switchMaterial.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
SharedPreferences.Editor editor = settingProperties.edit();
|
||||
if (isChecked) {
|
||||
show( "已开启实验性功能,可能并不起作用");
|
||||
editor.putBoolean("setting_autobeta1", true);
|
||||
} else {
|
||||
editor.putBoolean("setting_autobeta1", false);
|
||||
}
|
||||
editor.apply();
|
||||
});
|
||||
|
||||
shuiyuEditText = binding.shuiyu;
|
||||
luoxueEditText = binding.luoxue;
|
||||
userId = binding.qqbot;
|
||||
|
||||
MaterialButton openQQBot = binding.openQQbot;
|
||||
openQQBot.setOnClickListener(v -> {
|
||||
try {
|
||||
Intent intent = new Intent(getContext(), LinkQQBot.class);
|
||||
startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
loadSettings();
|
||||
|
||||
MaterialButton saveButton = binding.saveSettingsButton;
|
||||
saveButton.setOnClickListener(v -> {
|
||||
saveSettings(switchMaterial.isChecked(), shuiyuEditText.getText().toString(), luoxueEditText.getText().toString(), userId.getText().toString());
|
||||
});
|
||||
MaterialButton changeButton = binding.changePhoto;
|
||||
changeButton.setOnClickListener(v -> openFileChooser());
|
||||
TextView uuid = binding.uuid;
|
||||
@SuppressLint("HardwareIds") String androidId = Settings.Secure.getString(getContext().getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||
uuid.setText("Android ID:" + androidId);
|
||||
uuid.setOnClickListener(v -> {
|
||||
ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
// 创建一个ClipData对象
|
||||
ClipData clip = ClipData.newPlainText("label", androidId);
|
||||
// 将ClipData对象设置到剪贴板中
|
||||
clipboard.setPrimaryClip(clip);
|
||||
show("已复制Android ID到剪切板");
|
||||
});
|
||||
TextView vits = binding.vits;
|
||||
vits.setText("App version:" + getAppVersionName() + "\nLatest version:");
|
||||
getLatestRelease();
|
||||
WebView webView = binding.develop;
|
||||
webView.setBackgroundColor(0x00000000);
|
||||
webView.getSettings().setJavaScriptEnabled(true);
|
||||
String url = "http://wekan.godserver.cn/b/eu5nNL7GzF9SLYc6i/findmaimaidx";
|
||||
webView.setWebViewClient(new WebViewClient() {
|
||||
@Override
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
super.onPageFinished(view, url);
|
||||
view.loadUrl("javascript:(function() { " +
|
||||
"document.body.style.backgroundColor = 'transparent'; " +
|
||||
"})()");
|
||||
}
|
||||
});
|
||||
webView.loadUrl(url); // 加载网页
|
||||
return root;
|
||||
}
|
||||
private void openFileChooser() {
|
||||
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
||||
intent.setType("image/*");
|
||||
if (intent.resolveActivity(getContext().getPackageManager()) != null) {
|
||||
startActivityForResult(intent, PICK_IMAGE_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
private String getAppVersionName() {
|
||||
try {
|
||||
PackageInfo packageInfo = getContext().getPackageManager().getPackageInfo(getContext().getPackageName(), 0);
|
||||
return packageInfo.versionName;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
Log.d("SettingActivity", "onActivityResult called with requestCode: " + requestCode + ", resultCode: " + resultCode);
|
||||
|
||||
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
|
||||
Uri uri = data.getData();
|
||||
startCropActivity(uri);
|
||||
} else if (requestCode == UCrop.REQUEST_CROP && resultCode == RESULT_OK) {
|
||||
handleCroppedImage(data);
|
||||
} else if (requestCode == UCrop.REQUEST_CROP && resultCode == UCrop.RESULT_ERROR) {
|
||||
final Throwable cropError = UCrop.getError(data);
|
||||
Log.e("SettingActivity", "Cropping failed: ", cropError);
|
||||
} else {
|
||||
Log.w("SettingActivity", "Unexpected result from image picker or cropper");
|
||||
}
|
||||
}
|
||||
|
||||
private void startCropActivity(Uri uri) {
|
||||
Uri destinationUri = Uri.fromFile(new File(requireActivity().getCacheDir(), "cropped_image.jpg"));
|
||||
|
||||
UCrop.Options options = new UCrop.Options();
|
||||
options.setCompressionQuality(90);
|
||||
options.setCompressionFormat(Bitmap.CompressFormat.JPEG);
|
||||
|
||||
// 计算屏幕宽高比
|
||||
float[] aspectRatio = getScreenAspectRatio();
|
||||
|
||||
UCrop.of(uri, destinationUri)
|
||||
.withAspectRatio(aspectRatio[0], aspectRatio[1]) // 设置裁剪比例为屏幕比例
|
||||
.withMaxResultSize(getScreenWidth(), getScreenHeight()) // 设置最大结果尺寸
|
||||
.withOptions(options)
|
||||
.start(getActivity());
|
||||
}
|
||||
|
||||
private void handleCroppedImage(Intent data) {
|
||||
Uri croppedUri = UCrop.getOutput(data);
|
||||
if (croppedUri != null) {
|
||||
try {
|
||||
Bitmap photo = MediaStore.Images.Media.getBitmap(getContext().getContentResolver(), croppedUri);
|
||||
if (photo != null) {
|
||||
File croppedFile = new File(getContext().getExternalFilesDir(null), "cropped_image.jpg");
|
||||
try (FileOutputStream out = new FileOutputStream(croppedFile)) {
|
||||
photo.compress(Bitmap.CompressFormat.JPEG, 90, out);
|
||||
SharedPreferences.Editor editor = settingProperties.edit();
|
||||
editor.putString("image_uri", croppedUri.toString());
|
||||
editor.apply();
|
||||
show("成功");
|
||||
Log.d("SettingActivity", "图片已保存到: " + croppedFile.getAbsolutePath());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
show("失败");
|
||||
Log.e("SettingActivity", "保存图片失败: ", e);
|
||||
}
|
||||
} else {
|
||||
show("无法获取裁剪后的图片");
|
||||
Log.w("SettingActivity", "无法获取裁剪后的图片");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
show("无法获取裁剪后的图片");
|
||||
Log.e("SettingActivity", "无法获取裁剪后的图片: ", e);
|
||||
}
|
||||
} else {
|
||||
show("无法找到裁剪后的图片");
|
||||
Log.w("SettingActivity", "无法找到裁剪后的图片");
|
||||
}
|
||||
}
|
||||
|
||||
private void saveSettings(boolean betaEnabled, String shuiyuUsername, String luoxueUsername, String userId) {
|
||||
SharedPreferences.Editor editor = settingProperties.edit();
|
||||
MaterialRadioButton materialRadioButton = binding.radioButton1;
|
||||
MaterialRadioButton org = binding.org;
|
||||
int use = 0;
|
||||
if (org.isChecked()) {
|
||||
use = 0;
|
||||
} else if (materialRadioButton.isChecked()) {
|
||||
use = 1;
|
||||
} else {
|
||||
use = 2;
|
||||
}
|
||||
editor.putInt("use_", use);
|
||||
editor.putBoolean("setting_autobeta1", betaEnabled);
|
||||
editor.putString("shuiyu_username", shuiyuUsername);
|
||||
editor.putString("luoxue_username", luoxueUsername);
|
||||
editor.putString("userId", userId);
|
||||
editor.apply();
|
||||
show("设置已保存");
|
||||
}
|
||||
|
||||
private void loadSettings() {
|
||||
SwitchMaterial switchMaterial = binding.switchBeta1;
|
||||
shuiyuEditText = binding.shuiyu;
|
||||
luoxueEditText = binding.luoxue;
|
||||
MaterialRadioButton materialRadioButton = binding.radioButton1;
|
||||
MaterialRadioButton materialRadioButton2 = binding.radioButton2;
|
||||
MaterialRadioButton org = binding.org;
|
||||
switchMaterial.setChecked(settingProperties.getBoolean("setting_autobeta1", false));
|
||||
shuiyuEditText.setText(settingProperties.getString("shuiyu_username", ""));
|
||||
luoxueEditText.setText(settingProperties.getString("luoxue_username", ""));
|
||||
userId.setText(settingProperties.getString("userId", ""));
|
||||
|
||||
int use_ = settingProperties.getInt("use_", 1);
|
||||
if (use_ == 0) {
|
||||
use_ = 0;
|
||||
org.setChecked(true);
|
||||
SharedPreferences.Editor editorSetting = settingProperties.edit();
|
||||
editorSetting.putInt("use_", use_);
|
||||
editorSetting.apply();
|
||||
} else if (use_ == 1) {
|
||||
materialRadioButton.setChecked(true);
|
||||
} else if (use_ == 2) {
|
||||
materialRadioButton2.setChecked(true);
|
||||
}
|
||||
SharedPreferences mContextSp = this.getContext().getSharedPreferences(
|
||||
"updater.data",
|
||||
Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editorSetting = settingProperties.edit();
|
||||
String username = mContextSp.getString("username", "");
|
||||
if (Objects.requireNonNull(shuiyuEditText.getText()).toString().isEmpty()) {
|
||||
if (mContextSp.contains("username")) {
|
||||
editorSetting.putString("shuiyu_username", username);
|
||||
editorSetting.apply();
|
||||
shuiyuEditText.setText(username);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void getLatestRelease() {
|
||||
GitHubApiService service = GitHubApiClient.getClient();
|
||||
Call<Release> call = service.getLatestRelease("Spaso1", "FindMaimaiDX_Phone"); // 替换为你的仓库信息
|
||||
|
||||
call.enqueue(new Callback<Release>() {
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Release> call, @NonNull Response<Release> response) {
|
||||
if (response.isSuccessful()) {
|
||||
Release release = response.body();
|
||||
if (release != null) {
|
||||
String tagName = release.getTagName();
|
||||
String name = release.getName();
|
||||
String body = release.getBody();
|
||||
String htmlUrl = release.getHtmlUrl();
|
||||
TextView textView = binding.vits;
|
||||
textView.setText(textView.getText() + tagName + "\n" + name + "\n" + body);
|
||||
//Toast.makeText(SettingActivity.this, "Latest Release:\nTag Name: " + tagName + "\nName: " + name + "\nBody: " + body + "\nHTML URL: " + htmlUrl, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Release> call, @NonNull Throwable t) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private int getScreenWidth() {
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
requireActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||
return displayMetrics.widthPixels;
|
||||
}
|
||||
|
||||
private int getScreenHeight() {
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
requireActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||
return displayMetrics.heightPixels;
|
||||
}
|
||||
|
||||
private float[] getScreenAspectRatio() {
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||
float width = displayMetrics.widthPixels;
|
||||
float height = displayMetrics.heightPixels;
|
||||
return new float[]{width, height};
|
||||
}
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.astral.findmaimaiultra.ui.slideshow;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
public class SlideshowViewModel extends ViewModel {
|
||||
|
||||
private final MutableLiveData<String> mText;
|
||||
|
||||
public SlideshowViewModel() {
|
||||
mText = new MutableLiveData<>();
|
||||
mText.setValue("This is slideshow fragment");
|
||||
}
|
||||
|
||||
public LiveData<String> getText() {
|
||||
return mText;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.astral.findmaimaiultra.utill;
|
||||
|
||||
|
||||
import org.astral.findmaimaiultra.ui.home.HomeFragment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AddressParser {
|
||||
|
||||
public static void parseAddress(String address) {
|
||||
try {
|
||||
// 定义正则表达式
|
||||
String regex = "(.*?省|.*?市|.*?自治区|.*?自治州|.*?区|.*?县)(.*?市|.*?区|.*?县)";
|
||||
|
||||
// 创建Pattern对象
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
|
||||
// 创建Matcher对象
|
||||
Matcher matcher = pattern.matcher(address);
|
||||
|
||||
if (matcher.find()) {
|
||||
String province = matcher.group(1);
|
||||
String city = matcher.group(2);
|
||||
List<String> zhixiashi = new ArrayList<>();
|
||||
zhixiashi.add("北京市");
|
||||
zhixiashi.add("上海市");
|
||||
zhixiashi.add("重庆市");
|
||||
zhixiashi.add("天津市");
|
||||
|
||||
if(zhixiashi.contains(province)) {
|
||||
city = province;
|
||||
}
|
||||
|
||||
HomeFragment.city = city;
|
||||
HomeFragment.province = province;
|
||||
} else {
|
||||
System.out.println("无法解析地址");
|
||||
if(address.contains("市")) {
|
||||
if(address.contains("北京市")) {
|
||||
HomeFragment.city = "北京市";
|
||||
HomeFragment.province = "北京市";
|
||||
}else if(address.contains("上海市")) {
|
||||
HomeFragment.city = "上海市";
|
||||
HomeFragment.province = "上海市";
|
||||
}else if(address.contains("重庆市")) {
|
||||
HomeFragment.city = "重庆市";
|
||||
HomeFragment.province = "重庆市";
|
||||
}else if(address.contains("天津市")) {
|
||||
HomeFragment.city = "天津市";
|
||||
HomeFragment.province = "天津市";
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (Exception e) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.astral.findmaimaiultra.utill;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
public class DeviceInfoUtils {
|
||||
|
||||
/**
|
||||
* 获取设备的机型
|
||||
*
|
||||
* @return 设备的机型
|
||||
*/
|
||||
public static String getDeviceModel() {
|
||||
return Build.MODEL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备的Android版本号
|
||||
*
|
||||
* @return 设备的Android版本号
|
||||
*/
|
||||
public static String getAndroidVersion() {
|
||||
return Build.VERSION.RELEASE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备的Android版本号(整数形式)
|
||||
*
|
||||
* @return 设备的Android版本号(整数形式)
|
||||
*/
|
||||
public static int getAndroidVersionCode() {
|
||||
return Build.VERSION.SDK_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整的设备信息
|
||||
*
|
||||
* @return 包含机型和Android版本的字符串
|
||||
*/
|
||||
public static String getDeviceInfo() {
|
||||
return "设备机型: " + getDeviceModel() + ", Android版本: " + getAndroidVersion();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.astral.findmaimaiultra.utill;
|
||||
|
||||
import org.astral.findmaimaiultra.service.GitHubApiService;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
public class GitHubApiClient {
|
||||
private static final String BASE_URL = "https://api.github.com/";
|
||||
private static Retrofit retrofit = null;
|
||||
|
||||
public static GitHubApiService getClient() {
|
||||
if (retrofit == null) {
|
||||
retrofit = new Retrofit.Builder()
|
||||
.baseUrl(BASE_URL)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build();
|
||||
}
|
||||
return retrofit.create(GitHubApiService.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.astral.findmaimaiultra.utill;
|
||||
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import org.astral.findmaimaiultra.been.ChartPlay;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class NetworkUtils {
|
||||
private static final String BASE_URL = "http://mai.godserver.cn:11451/api/chartPlays/charts";
|
||||
|
||||
public static void fetchChartPlays(Callback callback) {
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
Request request = new Request.Builder().url(BASE_URL).build();
|
||||
client.newCall(request).enqueue(callback);
|
||||
}
|
||||
|
||||
public static List<ChartPlay> parseChartPlays(String responseBody) throws JSONException {
|
||||
List<ChartPlay> chartPlayList = new ArrayList<>();
|
||||
JSONObject jsonObject = new JSONObject(responseBody);
|
||||
JSONArray jsonArray = jsonObject.getJSONArray("content");
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject chartJson = jsonArray.getJSONObject(i);
|
||||
ChartPlay chartPlay = new ChartPlay();
|
||||
chartPlay.setSongName(chartJson.getString("songName"));
|
||||
chartPlay.setLength(chartJson.getString("length"));
|
||||
chartPlay.setDifficulty(chartJson.getString("difficulty"));
|
||||
chartPlay.setChartZipUrl(chartJson.getString("chartZipUrl"));
|
||||
chartPlay.setLikes(chartJson.getInt("likes"));
|
||||
chartPlay.setDownloads(chartJson.getInt("downloads"));
|
||||
chartPlay.setAuthor(chartJson.getString("author"));
|
||||
chartPlay.setId(chartJson.getInt("id"));
|
||||
chartPlay.setUsed(chartJson.getBoolean("used"));
|
||||
chartPlayList.add(chartPlay);
|
||||
}
|
||||
return chartPlayList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package org.astral.findmaimaiultra.utill;
|
||||
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import org.astral.findmaimaiultra.been.Place;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SharedViewModel extends ViewModel {
|
||||
private final MutableLiveData<Map<String, String>> sharedMap = new MutableLiveData<>();
|
||||
private final MutableLiveData<ArrayList<Place>> placelist = new MutableLiveData<>();
|
||||
|
||||
|
||||
public SharedViewModel() {
|
||||
placelist.setValue(null);
|
||||
sharedMap.setValue(new HashMap<>());
|
||||
}
|
||||
public MutableLiveData<ArrayList<Place>> getPlacelist() {
|
||||
return placelist;
|
||||
}
|
||||
public MutableLiveData<Map<String, String>> getSharedMap() {
|
||||
return sharedMap;
|
||||
}
|
||||
|
||||
public void addToMap(String key, String value) {
|
||||
Map<String, String> currentMap = sharedMap.getValue();
|
||||
if (currentMap != null) {
|
||||
currentMap.put(key, value);
|
||||
sharedMap.setValue(currentMap);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeFromMap(String key) {
|
||||
Map<String, String> currentMap = sharedMap.getValue();
|
||||
if (currentMap != null) {
|
||||
currentMap.remove(key);
|
||||
sharedMap.setValue(currentMap);
|
||||
}
|
||||
}
|
||||
public void setPlacelist(ArrayList<Place> placelist) {
|
||||
this.placelist.setValue(placelist);
|
||||
}
|
||||
public void clearMap() {
|
||||
sharedMap.setValue(new HashMap<>());
|
||||
}
|
||||
public void clearPlacelist() {
|
||||
placelist.setValue(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.astral.findmaimaiultra.utill;
|
||||
|
||||
|
||||
import org.astral.findmaimaiultra.been.PlayerData;
|
||||
import org.astral.findmaimaiultra.been.lx.Lx_chart;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Shuiyu2Luoxue {
|
||||
public static ArrayList<Lx_chart> shuiyu2luoxue(PlayerData playerData) {
|
||||
ArrayList<Lx_chart> lx_charts = new ArrayList<>();
|
||||
for (int i = 0; i < playerData.getCharts().getDx().size(); i++) {
|
||||
Lx_chart lx_chart = new Lx_chart();
|
||||
if(playerData.getCharts().getDx().get(i).getSongId() > 10000) {
|
||||
lx_chart.setId(playerData.getCharts().getDx().get(i).getSongId() - 10000);
|
||||
}else {
|
||||
lx_chart.setId(playerData.getCharts().getDx().get(i).getSongId());
|
||||
}
|
||||
lx_chart.setSong_name(playerData.getCharts().getDx().get(i).getTitle());
|
||||
lx_chart.setLevel(playerData.getCharts().getDx().get(i).getLevel());
|
||||
lx_chart.setLevel_index(playerData.getCharts().getDx().get(i).getLevel_index());
|
||||
lx_chart.setAchievements(playerData.getCharts().getDx().get(i).getAchievements());
|
||||
lx_chart.setDx_rating(playerData.getCharts().getDx().get(i).getRa());
|
||||
lx_chart.setDx_score(playerData.getCharts().getDx().get(i).getDxScore());
|
||||
lx_chart.setFs(playerData.getCharts().getDx().get(i).getFs());
|
||||
lx_chart.setFc(playerData.getCharts().getDx().get(i).getFc());
|
||||
if(lx_chart.getFc().equals("")) {
|
||||
lx_chart.setFc(null);
|
||||
}
|
||||
if(lx_chart.getFs().equals("")) {
|
||||
lx_chart.setFs(null);
|
||||
}
|
||||
lx_chart.setRate(playerData.getCharts().getDx().get(i).getRate());
|
||||
if(playerData.getCharts().getDx().get(i).getType().equals("SD")) {
|
||||
lx_chart.setType("standard");
|
||||
}else if(playerData.getCharts().getDx().get(i).getType().equals("DX")) {
|
||||
lx_chart.setType("dx");
|
||||
}
|
||||
// 获取当前时间戳
|
||||
Instant now = Instant.now();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
|
||||
// 格式化时间为ISO 8601字符串
|
||||
String iso8601String = now.toString().split("\\.")[0] + "Z";
|
||||
lx_chart.setUpload_time(iso8601String);
|
||||
lx_charts.add(lx_chart);
|
||||
}
|
||||
for (int i = 0; i < playerData.getCharts().getSd().size(); i++) {
|
||||
Lx_chart lx_chart = new Lx_chart();
|
||||
if(playerData.getCharts().getSd().get(i).getSongId() > 10000) {
|
||||
lx_chart.setId(playerData.getCharts().getSd().get(i).getSongId() - 10000);
|
||||
}else {
|
||||
lx_chart.setId(playerData.getCharts().getSd().get(i).getSongId());
|
||||
}
|
||||
lx_chart.setSong_name(playerData.getCharts().getSd().get(i).getTitle());
|
||||
lx_chart.setLevel(playerData.getCharts().getSd().get(i).getLevel());
|
||||
lx_chart.setLevel_index(playerData.getCharts().getSd().get(i).getLevel_index());
|
||||
lx_chart.setAchievements(playerData.getCharts().getSd().get(i).getAchievements());
|
||||
lx_chart.setDx_rating(playerData.getCharts().getSd().get(i).getRa());
|
||||
lx_chart.setDx_score(playerData.getCharts().getSd().get(i).getDxScore());
|
||||
lx_chart.setFs(playerData.getCharts().getSd().get(i).getFs());
|
||||
lx_chart.setFc(playerData.getCharts().getSd().get(i).getFc());
|
||||
if(lx_chart.getFc().equals("")) {
|
||||
lx_chart.setFc(null);
|
||||
}
|
||||
if(lx_chart.getFs().equals("")) {
|
||||
lx_chart.setFs(null);
|
||||
}
|
||||
lx_chart.setRate(playerData.getCharts().getSd().get(i).getRate());
|
||||
if (playerData.getCharts().getSd().get(i).getType().equals("SD")) {
|
||||
lx_chart.setType("standard");
|
||||
} else if (playerData.getCharts().getSd().get(i).getType().equals("DX")) {
|
||||
lx_chart.setType("dx");
|
||||
}
|
||||
Instant now = Instant.now();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
|
||||
String iso8601String = now.toString().split("\\.")[0] + "Z";
|
||||
lx_chart.setUpload_time(iso8601String);
|
||||
lx_charts.add(lx_chart);
|
||||
}
|
||||
return lx_charts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package org.astral.findmaimaiultra.utill;
|
||||
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.MediaStore;
|
||||
import androidx.loader.content.CursorLoader;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class UriToFileConverter {
|
||||
|
||||
public static File uriToFile(Context context, Uri uri) {
|
||||
String filePath = getRealPathFromURI(context, uri);
|
||||
if (filePath != null) {
|
||||
return new File(filePath);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getRealPathFromURI(Context context, Uri uri) {
|
||||
String filePath = null;
|
||||
if ("content".equalsIgnoreCase(uri.getScheme())) {
|
||||
String[] projection = { MediaStore.Images.Media.DATA };
|
||||
CursorLoader loader = new CursorLoader(context, uri, projection, null, null, null);
|
||||
Cursor cursor = loader.loadInBackground();
|
||||
if (cursor != null) {
|
||||
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
||||
cursor.moveToFirst();
|
||||
filePath = cursor.getString(column_index);
|
||||
cursor.close();
|
||||
}
|
||||
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
|
||||
filePath = uri.getPath();
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
|
||||
if (isExternalStorageDocument(uri)) {
|
||||
String docId = DocumentsContract.getDocumentId(uri);
|
||||
String[] split = docId.split(":");
|
||||
String type = split[0];
|
||||
if ("primary".equalsIgnoreCase(type)) {
|
||||
filePath = Environment.getExternalStorageDirectory() + "/" + split[1];
|
||||
}
|
||||
} else if (isDownloadsDocument(uri)) {
|
||||
String id = DocumentsContract.getDocumentId(uri);
|
||||
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
|
||||
filePath = getDataColumn(context, contentUri, null, null);
|
||||
} else if (isMediaDocument(uri)) {
|
||||
String docId = DocumentsContract.getDocumentId(uri);
|
||||
String[] split = docId.split(":");
|
||||
String type = split[0];
|
||||
Uri contentUri = null;
|
||||
if ("image".equals(type)) {
|
||||
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("video".equals(type)) {
|
||||
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("audio".equals(type)) {
|
||||
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
}
|
||||
String selection = "_id=?";
|
||||
String[] selectionArgs = new String[] { split[1] };
|
||||
filePath = getDataColumn(context, contentUri, selection, selectionArgs);
|
||||
}
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
|
||||
private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
|
||||
Cursor cursor = null;
|
||||
String column = MediaStore.Images.Media.DATA;
|
||||
String[] projection = { column };
|
||||
try {
|
||||
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
int index = cursor.getColumnIndexOrThrow(column);
|
||||
return cursor.getString(index);
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isExternalStorageDocument(Uri uri) {
|
||||
return "com.android.externalstorage.documents".equals(uri.getAuthority());
|
||||
}
|
||||
|
||||
private static boolean isDownloadsDocument(Uri uri) {
|
||||
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
|
||||
}
|
||||
|
||||
private static boolean isMediaDocument(Uri uri) {
|
||||
return "com.android.providers.media.documents".equals(uri.getAuthority());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package org.astral.findmaimaiultra.utill;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
public class ZoomableViewGroup extends FrameLayout {
|
||||
private ScaleGestureDetector scaleGestureDetector;
|
||||
private GestureDetector gestureDetector;
|
||||
private final Matrix matrix = new Matrix();
|
||||
private float scaleFactor = 1.0f;
|
||||
public static float lastX, lastY;
|
||||
private static final long REFRESH_RATE = 5; // 11ms 对应大约 90fps
|
||||
private Handler mHandler;
|
||||
private Runnable mRefreshRunnable;
|
||||
|
||||
public ZoomableViewGroup(Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public ZoomableViewGroup(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public ZoomableViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
scaleGestureDetector = new ScaleGestureDetector(context, new ScaleListener());
|
||||
gestureDetector = new GestureDetector(context, new GestureListener());
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
mRefreshRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
invalidate(); // 重新绘制视图
|
||||
mHandler.postDelayed(this, REFRESH_RATE);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
scaleGestureDetector.onTouchEvent(event);
|
||||
gestureDetector.onTouchEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
|
||||
@Override
|
||||
public boolean onScale(ScaleGestureDetector detector) {
|
||||
scaleFactor *= detector.getScaleFactor();
|
||||
scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 5.0f)); // 限制缩放范围
|
||||
|
||||
matrix.postScale(detector.getScaleFactor(), detector.getScaleFactor(), detector.getFocusX(), detector.getFocusY());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||
// 取反 distanceX 和 distanceY
|
||||
matrix.postTranslate(-distanceX, -distanceY);
|
||||
|
||||
lastX = e2.getX();
|
||||
lastY = e2.getY();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDown(MotionEvent e) {
|
||||
lastX = e.getX();
|
||||
lastY = e.getY();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
canvas.save();
|
||||
canvas.concat(matrix);
|
||||
super.dispatchDraw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
startRefreshing();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
stopRefreshing();
|
||||
}
|
||||
|
||||
private void startRefreshing() {
|
||||
mHandler.post(mRefreshRunnable);
|
||||
}
|
||||
|
||||
private void stopRefreshing() {
|
||||
mHandler.removeCallbacks(mRefreshRunnable);
|
||||
}
|
||||
}
|
||||
31
app/src/main/res/####values-night/colors.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="purple_200">#673AB7</color>
|
||||
<color name="purple_500">#673AB7</color>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="teal_200">#045D53</color>
|
||||
<color name="night">#673AB7</color>
|
||||
<color name="border_color">#FFFFFF</color> <!-- 白色 -->
|
||||
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#8A8282</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
<color name="primary">#673AB7</color>
|
||||
<color name="primary_dark">#673AB7</color>
|
||||
<color name="primary_light">#673AB7</color>
|
||||
<color name="accent">#3F51B5</color>
|
||||
<color name="primary_text">#212121</color>
|
||||
<color name="secondary_text">#727272</color>
|
||||
<color name="icons">#FFFFFF</color>
|
||||
<color name="divider">#B6B6B6</color>
|
||||
<color name="colorPrimary">#673AB7</color>
|
||||
<color name="colorPrimaryVariant">#673AB7</color>
|
||||
<color name="colorOnPrimary">#141313</color>
|
||||
<color name="colorSecondary">#045D53</color>
|
||||
<color name="colorSecondaryVariant">#018786</color>
|
||||
<color name="colorOnSecondary">#000000</color>
|
||||
<color name="lineBaseGreen">#045D53</color>
|
||||
<color name="VlineBaseGreen">#C2F6C4</color>
|
||||
<color name="textcolorPrimary">#FFFFFF</color>
|
||||
<color name="red">#F44336</color>
|
||||
</resources>
|
||||
7
app/src/main/res/####values-night/styles.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- res/values-night/styles.xml -->
|
||||
<resources>
|
||||
<style name="BorderStyle">
|
||||
<item name="android:background">@drawable/border</item>
|
||||
</style>
|
||||
</resources>
|
||||
69
app/src/main/res/####values-night/themes.xml
Normal file
@@ -0,0 +1,69 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.FindMaimaiDX" parent="Theme.AppCompat.NoActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">#673AB7</item>
|
||||
<item name="colorPrimaryVariant">#2C2A30</item>
|
||||
<item name="colorOnPrimary">@color/white</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/night</item>
|
||||
<item name="colorSecondaryVariant">@color/night</item>
|
||||
<item name="colorOnSecondary">@color/night</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor">@color/night</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
<style name="Theme.FindMaimaiDX2" parent="Theme.AppCompat.NoActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/night</item>
|
||||
<item name="colorPrimaryVariant">#673AB7</item>
|
||||
<item name="colorOnPrimary">@color/white</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/night</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_700</item>
|
||||
<item name="colorOnSecondary">@color/night</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor">#FFFFFF</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
<style name="FindMaimaiDX2" parent="Theme.AppCompat.NoActionBar">
|
||||
<item name="colorPrimary">@color/night</item>
|
||||
<item name="colorPrimaryVariant">@color/night</item>
|
||||
<item name="colorOnPrimary">@color/night</item>
|
||||
<item name="colorSecondary">@color/colorSecondary</item>
|
||||
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
|
||||
<item name="colorOnSecondary">@color/colorOnSecondary</item>
|
||||
<item name="android:statusBarColor">@color/night</item>
|
||||
</style>
|
||||
<!-- Base application theme. -->
|
||||
<style name="NewTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/night</item>
|
||||
<item name="colorPrimaryVariant">@color/night</item>
|
||||
<item name="colorOnPrimary">@color/colorOnPrimary</item>
|
||||
<item name="colorSecondary">@color/colorSecondary</item>
|
||||
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
|
||||
<item name="colorOnSecondary">@color/colorOnSecondary</item>
|
||||
<item name="android:statusBarColor">@color/night</item>
|
||||
</style>
|
||||
<!-- MaterialCardView 样式 -->
|
||||
<style name="CustomMaterialCardView" parent="Widget.MaterialComponents.CardView"> <item name="cardCornerRadius">16dp</item>
|
||||
<item name="cardElevation">8dp</item>
|
||||
<item name="cardBackgroundColor">@color/white</item>
|
||||
</style>
|
||||
|
||||
<!-- 上方 TextView 样式 -->
|
||||
<style name="TopTextViewStyle"> <item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:textColor">@color/black</item>
|
||||
<item name="android:padding">16dp</item>
|
||||
<item name="android:layout_alignParentTop">true</item>
|
||||
</style>
|
||||
|
||||
<!-- 下方 TextView 样式 -->
|
||||
<style name="BottomTextViewStyle"> <item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:textColor">@android:color/black</item>
|
||||
<item name="android:padding">16dp</item>
|
||||
</style>
|
||||
</resources>
|
||||
7
app/src/main/res/drawable/border.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- res/drawable/border.xml -->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@android:color/transparent" />
|
||||
<stroke android:width="1dp" android:color="@color/border_color" />
|
||||
<padding android:left="1dp" android:top="1dp" android:right="1dp" android:bottom="1dp" />
|
||||
</shape>
|
||||
5
app/src/main/res/drawable/bot_message_background.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#D5C4ED" />
|
||||
<corners android:radius="8dp" />
|
||||
</shape>
|
||||
5
app/src/main/res/drawable/button_background.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#007AFF" />
|
||||
<corners android:radius="24dp" />
|
||||
</shape>
|
||||
BIN
app/src/main/res/drawable/dx.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
9
app/src/main/res/drawable/edit_text_background.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#FFFFFF" />
|
||||
<corners android:radius="8dp" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#BDBDBD" />
|
||||
</shape>
|
||||
9
app/src/main/res/drawable/edittext_background.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<!-- res/drawable/edittext_background.xml -->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#7F8183"/>
|
||||
<corners android:radius="8dp" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#E91E63" />
|
||||
</shape>
|
||||
BIN
app/src/main/res/drawable/fcfs.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
app/src/main/res/drawable/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
app/src/main/res/drawable/ic_launcher2.png
Normal file
|
After Width: | Height: | Size: 381 KiB |
74
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="108dp"
|
||||
android:width="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108">
|
||||
<path android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
</vector>
|
||||
31
app/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<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:startY="49.59793"
|
||||
android:startX="42.9492"
|
||||
android:endY="92.4963"
|
||||
android:endX="85.84757"
|
||||
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: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:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
||||
12
app/src/main/res/drawable/ic_menu_camera.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M9,2L7.17,4H4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2H9zm3,15c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_menu_gallery.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M22,16V4c0,-1.1 -0.9,-2 -2,-2H8c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2zm-11,-4l2.03,2.71L16,11l4,5H8l3,-4zM2,6v14c0,1.1 0.9,2 2,2h14v-2H4V6H2z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_menu_slideshow.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M4,6H2v14c0,1.1 0.9,2 2,2h14v-2H4V6zm16,-4H8c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2zm-8,12.5v-9l6,4.5 -6,4.5z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/id_add.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
|
||||
</vector>
|
||||
5
app/src/main/res/drawable/input_background.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#FFFFFF" />
|
||||
<corners android:radius="24dp" />
|
||||
</shape>
|
||||
6
app/src/main/res/drawable/link_background.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#E0E0E0" />
|
||||
<corners android:radius="8dp" />
|
||||
</shape>
|
||||
BIN
app/src/main/res/drawable/logo.png
Normal file
|
After Width: | Height: | Size: 323 KiB |
BIN
app/src/main/res/drawable/placeholder.jpg
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
BIN
app/src/main/res/drawable/rank_a.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
app/src/main/res/drawable/rank_aa.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
app/src/main/res/drawable/rank_aaa.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
app/src/main/res/drawable/rank_b.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/drawable/rank_bb.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
app/src/main/res/drawable/rank_bbb.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
app/src/main/res/drawable/rank_c.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
app/src/main/res/drawable/rank_d.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
app/src/main/res/drawable/rank_s.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
app/src/main/res/drawable/rank_sp.png
Normal file
|
After Width: | Height: | Size: 21 KiB |