commit 8443a94b73c646c486e4c778dfad84007a0dc41a Author: Spaso1 Date: Mon Mar 24 21:43:54 2025 +0800 commit diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b589d56 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..efd7cbf --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..ec453bb --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..e262dfc --- /dev/null +++ b/app/build.gradle @@ -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' +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/app/src/androidTest/java/org/astral/findmaimaiultra/ExampleInstrumentedTest.java b/app/src/androidTest/java/org/astral/findmaimaiultra/ExampleInstrumentedTest.java new file mode 100644 index 0000000..e380724 --- /dev/null +++ b/app/src/androidTest/java/org/astral/findmaimaiultra/ExampleInstrumentedTest.java @@ -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 Testing documentation + */ +@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()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..e3d2c94 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/org/astral/findmaimaiultra/adapter/PlaceAdapter.java b/app/src/main/java/org/astral/findmaimaiultra/adapter/PlaceAdapter.java new file mode 100644 index 0000000..c07be33 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/adapter/PlaceAdapter.java @@ -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 { + + private List placeList; + private OnItemClickListener listener; + + public interface OnItemClickListener { + void onItemClick(Place place); + } + + public PlaceAdapter(List 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); + } + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/adapter/ReviewAdapter.java b/app/src/main/java/org/astral/findmaimaiultra/adapter/ReviewAdapter.java new file mode 100644 index 0000000..193441d --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/adapter/ReviewAdapter.java @@ -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 { + + private List reviews; + + public ReviewAdapter(List 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); + } + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/AiLog.java b/app/src/main/java/org/astral/findmaimaiultra/been/AiLog.java new file mode 100644 index 0000000..4a6475e --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/AiLog.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/AiUserMessage.java b/app/src/main/java/org/astral/findmaimaiultra/been/AiUserMessage.java new file mode 100644 index 0000000..b6deb94 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/AiUserMessage.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/AmapReverseGeocodeResponse.java b/app/src/main/java/org/astral/findmaimaiultra/been/AmapReverseGeocodeResponse.java new file mode 100644 index 0000000..ee8e7f3 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/AmapReverseGeocodeResponse.java @@ -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 city; + + public String getProvince() { + return province; + } + + public List getCity() { + return city; + } + + public void setProvince(String province) { + this.province = province; + } + + public void setCity(List city) { + this.city = city; + } + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/Chart.java b/app/src/main/java/org/astral/findmaimaiultra/been/Chart.java new file mode 100644 index 0000000..7435138 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/Chart.java @@ -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 +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/ChartPlay.java b/app/src/main/java/org/astral/findmaimaiultra/been/ChartPlay.java new file mode 100644 index 0000000..d7e241c --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/ChartPlay.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/Charts.java b/app/src/main/java/org/astral/findmaimaiultra/been/Charts.java new file mode 100644 index 0000000..f4685b4 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/Charts.java @@ -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 dx; + @SerializedName("sd") + private List sd; + + // Getters and Setters + + public List getDx() { + return dx; + } + + public void setDx(List dx) { + this.dx = dx; + } + + public List getSd() { + return sd; + } + + public void setSd(List sd) { + this.sd = sd; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/ChatMessage.java b/app/src/main/java/org/astral/findmaimaiultra/been/ChatMessage.java new file mode 100644 index 0000000..840f411 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/ChatMessage.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/CompassView.java b/app/src/main/java/org/astral/findmaimaiultra/been/CompassView.java new file mode 100644 index 0000000..7f95dcb --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/CompassView.java @@ -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); + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/Difficulty.java b/app/src/main/java/org/astral/findmaimaiultra/been/Difficulty.java new file mode 100644 index 0000000..d938ecd --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/Difficulty.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/DistanceCalculator.java b/app/src/main/java/org/astral/findmaimaiultra/been/DistanceCalculator.java new file mode 100644 index 0000000..ff788a1 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/DistanceCalculator.java @@ -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"); + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/Geocode.java b/app/src/main/java/org/astral/findmaimaiultra/been/Geocode.java new file mode 100644 index 0000000..2a70e1a --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/Geocode.java @@ -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 CREATOR = new Creator() { + @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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/GpsData.java b/app/src/main/java/org/astral/findmaimaiultra/been/GpsData.java new file mode 100644 index 0000000..53dec83 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/GpsData.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/Market.java b/app/src/main/java/org/astral/findmaimaiultra/been/Market.java new file mode 100644 index 0000000..e54643b --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/Market.java @@ -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 + + '}'; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/Message.java b/app/src/main/java/org/astral/findmaimaiultra/been/Message.java new file mode 100644 index 0000000..3bf9fce --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/Message.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/Place.java b/app/src/main/java/org/astral/findmaimaiultra/been/Place.java new file mode 100644 index 0000000..7a7f61e --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/Place.java @@ -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 CREATOR = new Creator() { + @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); + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/PlaceContent.java b/app/src/main/java/org/astral/findmaimaiultra/been/PlaceContent.java new file mode 100644 index 0000000..9e12855 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/PlaceContent.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/PlayerData.java b/app/src/main/java/org/astral/findmaimaiultra/been/PlayerData.java new file mode 100644 index 0000000..9989689 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/PlayerData.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/Release.java b/app/src/main/java/org/astral/findmaimaiultra/been/Release.java new file mode 100644 index 0000000..92b3502 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/Release.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/RequestData.java b/app/src/main/java/org/astral/findmaimaiultra/been/RequestData.java new file mode 100644 index 0000000..42f3c7e --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/RequestData.java @@ -0,0 +1,30 @@ +package org.astral.findmaimaiultra.been; +// RequestData.java +import java.util.List; + +public class RequestData { + private String model; + private List messages; + + public RequestData(String model, List messages) { + this.model = model; + this.messages = messages; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public List getMessages() { + return messages; + } + + public void setMessages(List messages) { + this.messages = messages; + } +} + diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/ResponseData.java b/app/src/main/java/org/astral/findmaimaiultra/been/ResponseData.java new file mode 100644 index 0000000..8a996c7 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/ResponseData.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/faker/MusicRating.java b/app/src/main/java/org/astral/findmaimaiultra/been/faker/MusicRating.java new file mode 100644 index 0000000..a41fe4d --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/faker/MusicRating.java @@ -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; + } +} + diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/faker/QRCodeMessage.java b/app/src/main/java/org/astral/findmaimaiultra/been/faker/QRCodeMessage.java new file mode 100644 index 0000000..f43fe42 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/faker/QRCodeMessage.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/faker/RegionData.java b/app/src/main/java/org/astral/findmaimaiultra/been/faker/RegionData.java new file mode 100644 index 0000000..b25b17c --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/faker/RegionData.java @@ -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 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 getUserRegionList() { + return userRegionList; + } + + public void setUserRegionList(List userRegionList) { + this.userRegionList = userRegionList; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/faker/Udemae.java b/app/src/main/java/org/astral/findmaimaiultra/been/faker/Udemae.java new file mode 100644 index 0000000..49db4ab --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/faker/Udemae.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserData.java b/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserData.java new file mode 100644 index 0000000..80c7f7e --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserData.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserDataDetails.java b/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserDataDetails.java new file mode 100644 index 0000000..044e8a0 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserDataDetails.java @@ -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 charaSlot; + private List 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; + +} \ No newline at end of file diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserRating.java b/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserRating.java new file mode 100644 index 0000000..f91a1be --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserRating.java @@ -0,0 +1,61 @@ +package org.astral.findmaimaiultra.been.faker; + +import java.util.List; + +public class UserRating { + private int rating; + private List ratingList; + private List newRatingList; + private List nextRatingList; + private List nextNewRatingList; + private Udemae udemae; + + // Getters and Setters + public int getRating() { + return rating; + } + + public void setRating(int rating) { + this.rating = rating; + } + + public List getRatingList() { + return ratingList; + } + + public void setRatingList(List ratingList) { + this.ratingList = ratingList; + } + + public List getNewRatingList() { + return newRatingList; + } + + public void setNewRatingList(List newRatingList) { + this.newRatingList = newRatingList; + } + + public List getNextRatingList() { + return nextRatingList; + } + + public void setNextRatingList(List nextRatingList) { + this.nextRatingList = nextRatingList; + } + + public List getNextNewRatingList() { + return nextNewRatingList; + } + + public void setNextNewRatingList(List nextNewRatingList) { + this.nextNewRatingList = nextNewRatingList; + } + + public Udemae getUdemae() { + return udemae; + } + + public void setUdemae(Udemae udemae) { + this.udemae = udemae; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserRegion.java b/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserRegion.java new file mode 100644 index 0000000..2f581e5 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserRegion.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserScore.java b/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserScore.java new file mode 100644 index 0000000..b61944c --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/faker/UserScore.java @@ -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; + } +} + diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/lx/Difficulty.java b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Difficulty.java new file mode 100644 index 0000000..25ecf9a --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Difficulty.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_chart.java b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_chart.java new file mode 100644 index 0000000..a37fd90 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_chart.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_data.java b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_data.java new file mode 100644 index 0000000..b22d4c2 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_data.java @@ -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 standard; + + @SerializedName("dx") + private List 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 getStandard() { + return standard; + } + + public void setStandard(List standard) { + this.standard = standard; + } + + public List getDx() { + return dx; + } + + public void setDx(List dx) { + this.dx = dx; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_data_scores.java b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_data_scores.java new file mode 100644 index 0000000..c33d0d9 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_data_scores.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_playerInfo.java b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_playerInfo.java new file mode 100644 index 0000000..d9172eb --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_playerInfo.java @@ -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; + } + } + } diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_res.java b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_res.java new file mode 100644 index 0000000..5bba05f --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Lx_res.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/lx/Notes.java b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Notes.java new file mode 100644 index 0000000..1600ec9 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Notes.java @@ -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_; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/been/lx/Song.java b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Song.java new file mode 100644 index 0000000..a8584ad --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/been/lx/Song.java @@ -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 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 getDifficulties() { + return difficulties; + } + + public void setDifficulties(Map difficulties) { + this.difficulties = difficulties; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/map2d/BasicMapActivity.java b/app/src/main/java/org/astral/findmaimaiultra/map2d/BasicMapActivity.java new file mode 100644 index 0000000..b291765 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/map2d/BasicMapActivity.java @@ -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 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); + } +} + \ No newline at end of file diff --git a/app/src/main/java/org/astral/findmaimaiultra/message/ApiResponse.java b/app/src/main/java/org/astral/findmaimaiultra/message/ApiResponse.java new file mode 100644 index 0000000..b328934 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/message/ApiResponse.java @@ -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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/service/GitHubApiService.java b/app/src/main/java/org/astral/findmaimaiultra/service/GitHubApiService.java new file mode 100644 index 0000000..3834d68 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/service/GitHubApiService.java @@ -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 getLatestRelease(@Path("owner") String owner, @Path("repo") String repo); +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/LinkQQBot.java b/app/src/main/java/org/astral/findmaimaiultra/ui/LinkQQBot.java new file mode 100644 index 0000000..f25169b --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/ui/LinkQQBot.java @@ -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 userRegions) { + Collections.sort(userRegions, new Comparator() { + @Override + public int compare(UserRegion o1, UserRegion o2) { + return Integer.compare(o2.getPlayCount(), o1.getPlayCount()); + } + }); + // 处理排序后的数据,例如显示在表格中 + displaySortedUserRegions(userRegions); + } + + private void displaySortedUserRegions(List 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); + } + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/MainActivity.java b/app/src/main/java/org/astral/findmaimaiultra/ui/MainActivity.java new file mode 100644 index 0000000..a03048e --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/ui/MainActivity.java @@ -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(); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/PageActivity.java b/app/src/main/java/org/astral/findmaimaiultra/ui/PageActivity.java new file mode 100644 index 0000000..1b06859 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/ui/PageActivity.java @@ -0,0 +1,1186 @@ +package org.astral.findmaimaiultra.ui; + +import android.animation.AnimatorSet; +import android.animation.ArgbEvaluator; +import android.animation.ObjectAnimator; +import android.annotation.SuppressLint; +import android.app.AlertDialog; +import android.content.*; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Bundle; +import android.provider.Settings; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.*; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import com.baidu.mapapi.SDKInitializer; +import com.baidu.mapapi.map.*; +import com.baidu.mapapi.model.LatLng; +import com.google.android.material.button.MaterialButton; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import okhttp3.*; +import org.astral.findmaimaiultra.R; +import org.astral.findmaimaiultra.adapter.ReviewAdapter; +import org.astral.findmaimaiultra.been.Market; +import org.astral.findmaimaiultra.been.Place; +import org.astral.findmaimaiultra.been.PlaceContent; +import org.astral.findmaimaiultra.message.ApiResponse; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Type; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +public class PageActivity extends AppCompatActivity { + private double[] tagXY; + private String tagplace; + public static TextView t2 ; + private String type_code = "mai"; + public static List marketList = new ArrayList<>(); + public static LinearLayout t31 ; + public static Context context; + public static String key = ""; + public static List textViews = new ArrayList<>(); + private MaterialButton likeButton; + private MaterialButton disButton; + private boolean isLike = false; + private boolean isDis = false; + private String meituan = ""; + private String douyin = ""; + private SharedPreferences sp ; + private SharedPreferences shoucang ; + private TextView numberPeo; + private MaterialButton adminIt; + private OkHttpClient client; + private Place place; + public static int id; + private MapView mapView; + private BaiduMap baiduMap; + @Override + @SuppressLint({"MissingInflatedId", "Range", "SetTextI18n", "UnspecifiedRegisterReceiverFlag"}) + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + context = this; + + SDKInitializer.setAgreePrivacy(getApplicationContext(),true); + SDKInitializer.initialize(getApplicationContext()); + setContentView(R.layout.activity_page); + client = new OkHttpClient(); + /** + * 基础内容加载 + */ + String name = getIntent().getStringExtra("name").split(" ")[0]; + int id2 = getIntent().getIntExtra("id", 0); + String address = getIntent().getStringExtra("address"); + String province = getIntent().getStringExtra("province"); + String city = getIntent().getStringExtra("city"); + String area = getIntent().getStringExtra("area"); + double x = getIntent().getDoubleExtra("x", 0); + double y = getIntent().getDoubleExtra("y", 0); + int count = getIntent().getIntExtra("count", 0); + int good = getIntent().getIntExtra("good", 0); + int bad = getIntent().getIntExtra("bad", 0); + int num = getIntent().getIntExtra("num",0); + int numJ = getIntent().getIntExtra("numJ",0); + meituan = getIntent().getStringExtra("meituan"); + douyin = getIntent().getStringExtra("douyin"); + numberPeo = findViewById(R.id.numberPeo); + androidx.appcompat.widget.Toolbar toolbar = findViewById(R.id.toolbar); + toolbar.setTitle(" " + name); + TextView textView = findViewById(R.id.nameTextView); + textView.setText(name); + TextView textView2 = findViewById(R.id.addressTextView); + textView2.setText(address); + TextView textView3 = findViewById(R.id.provinceTextView); + textView3.setText(province); + TextView textView4 = findViewById(R.id.cityTextView); + textView4.setText(city); + TextView textView5 = findViewById(R.id.areaTextView); + textView5.setText(area); + TextView t1 = findViewById(R.id.num5); + adminIt = findViewById(R.id.admin); + t1.setText("舞萌总机台 " + (num + numJ)); + if(getIntent().hasExtra("type")) { + String type = getIntent().getStringExtra("type"); + type_code = "chu"; + t1.setText("中二总机台 " + (num + numJ)); + } + TextView t2 = findViewById(R.id.num6); + t2.setText("国机 " + num); + TextView t3 = findViewById(R.id.num7); + tagXY = new double[]{x,y}; + tagplace = name; + MaterialButton share = findViewById(R.id.share); + share.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clipData = ClipData.newPlainText("text", address ); + clipboardManager.setPrimaryClip(clipData); + Toast.makeText(PageActivity.this, "机厅地址信息已经复制!", Toast.LENGTH_SHORT).show(); + } + }); + MaterialButton bi = findViewById(R.id.bi); + bi.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View view) { + openLinkHub(meituan,douyin); + } + }); + + MaterialButton button = findViewById(R.id.button); + button.setText("导航"); + id = id2; + Log.d("id", String.valueOf(id)); + /** + * 获取附近商超 + */ + place = new Place(id2, name, province, city, area, address, 1, x, y, count, good, bad); + place.setNumJ(numJ); + place.setNum(num); + findnear(place); + + TextView tor2 = findViewById(R.id.textView2); + tor2.setText("\n附近商超"); + tor2.setTextSize(20.0F); + t31 = findViewById(R.id.hor); + + sp = getSharedPreferences("like@dis", MODE_PRIVATE); + shoucang = getSharedPreferences("shoucang@", MODE_PRIVATE); + getNumberPeo(); + SharedPreferences.Editor editor = sp.edit(); + SharedPreferences.Editor editor2 = shoucang.edit(); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // 在这里执行按钮点击时的操作 + tagXY[0] = x; + tagXY[1] = y; + tagplace = name; + startGeoIntent(); + } + }); + /** + * 添加点赞点踩效果 + */ + likeButton = findViewById(R.id.likeButton); + likeButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (isLike) { + startShakeAnimation(likeButton); + + }else { + if (isDis) { + backAnimation(disButton); + sendGetRequest(4); + } + isLike = true; + isDis = false; + startLikeAnimation(likeButton); + editor.remove(name); + editor.putString(name,"1"); + editor.apply(); + sendGetRequest(1); + } + } + }); + disButton = findViewById(R.id.disButton); + disButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (isDis) { + startShakeAnimation(disButton); + }else { + if (isLike) { + backAnimation(likeButton); + sendGetRequest(3); + } + isDis = true; + isLike = false; + startLikeAnimation(disButton); + editor.remove(name); + editor.putString(name,"0"); + editor.apply(); + sendGetRequest(2); + } + } + }); + + if(sp.contains(name)) { + if(sp.getString(name,"0").equals("1")) { + likeButton.setBackgroundColor(Color.parseColor("#FF0000")); + likeButton.setTextColor(Color.parseColor("#FFFFFF")); + isLike = true; + }else { + disButton.setBackgroundColor(Color.parseColor("#FF0000")); + disButton.setTextColor(Color.parseColor("#FFFFFF")); + isDis = true; + } + } + + /** + * 添加收藏 + */ + com.google.android.material.switchmaterial.SwitchMaterial switch1 = findViewById(R.id.switch1); + if(shoucang.contains(id2 + "")) { + switch1.setChecked(true); + } + switch1.setOnClickListener(new View.OnClickListener(){ + @Override + public void onClick(View view) { + if(switch1.isChecked()) { + editor2.putString(id2 + "","1"); + }else { + editor2.remove(id2 + ""); + } + editor2.apply(); + } + }); + /** + * 添加商超 + */ + MaterialButton addMarket = findViewById(R.id.add); + addMarket.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// 创建对话框构建器 + // 创建一个线性布局 + LinearLayout layout = new LinearLayout(PageActivity.context); + layout.setOrientation(LinearLayout.VERTICAL); + layout.setPadding(16, 16, 16, 16); + + // 创建店铺名称输入框 + EditText etShopName = new EditText(PageActivity.context); + etShopName.setHint("请输入店铺名称"); + layout.addView(etShopName); + + // 创建机厅距离输入框 + EditText etHallDistance = new EditText(PageActivity.context); + etHallDistance.setHint("请输入机厅距离(米)"); + layout.addView(etHallDistance); + + // 创建对话框构建器 + AlertDialog.Builder builder = new AlertDialog.Builder(PageActivity.context); + // 设置自定义布局 + builder.setView(layout); + + // 添加确定按钮 + builder.setPositiveButton("确定", (dialogInterface, i) -> { + String shopName = etShopName.getText().toString(); + String hallDistance = etHallDistance.getText().toString(); + Market market = new Market(); + market.setMarketName(shopName); + market.setParentId(id); + DecimalFormat decimalFormat = new DecimalFormat("0.#"); + double distance = Double.parseDouble(decimalFormat.format(Double.parseDouble(hallDistance) / 1000)); + market.setDistance(distance); + market.setType(1); + market.setX(place.getX()); + market.setY(place.getY()); + new SendMarketRequestTask().execute(market); + Log.d("body",market.toString()); + Toast.makeText(PageActivity.context, "已添加,等待审核", Toast.LENGTH_SHORT).show(); + }); + + // 添加取消按钮 + builder.setNegativeButton("取消", (dialogInterface, i) -> dialogInterface.dismiss()); + + // 创建对话框 + AlertDialog dialog = builder.create(); + + // 显示对话框 + dialog.show(); + } + }); + MaterialButton back = findViewById(R.id.updateButton); + back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + //创建一个可以输入数量的弹窗,在点击确定后执行指定操作 + AlertDialog.Builder builder = new AlertDialog.Builder(PageActivity.context); + LinearLayout layout = new LinearLayout(PageActivity.context); + layout.setOrientation(LinearLayout.VERTICAL); + EditText editText = new EditText(PageActivity.context); + editText.setHint("这是国框数量 目前是" + place.getNum() + "个"); + EditText editTextJ = new EditText(PageActivity.context); + editTextJ.setHint("这是\uD83D\uDCB3数量 目前是" + place.getNumJ() + "个"); + editTextJ.setText("0"); + layout.addView(editText); + layout.addView(editTextJ); + builder.setTitle("输入数量") + .setView(layout) + .setPositiveButton("确定", (dialog, which) -> { + String input = editText.getText().toString(); + Log.d("输入的数量是:", input); + try { + int inputNum = Integer.parseInt(input); + int inputJ = Integer.parseInt(editTextJ.getText().toString()); + sendUpdateNum(id,Integer.parseInt(input),inputJ); + }catch (Exception e) { + Toast.makeText(PageActivity.context, "请输入数字", Toast.LENGTH_SHORT).show(); + } + }) + .setNegativeButton("取消", null) + .show(); + + } + }); + WebView webView = findViewById(R.id.imageView1); + String imageUrl = "https://img.shields.io/badge/recommend-" + good + "-green"; + webView.setBackgroundColor(0x00000000); // 设置背景为透明 + + WebSettings webSettings = webView.getSettings(); + webSettings.setJavaScriptEnabled(true); // 启用JavaScript + webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); + webView.setWebViewClient(new WebViewClient() { + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + // 注入JavaScript来设置网页背景为透明 + view.loadUrl("javascript:(function() { " + + "document.body.style.backgroundColor = 'transparent'; " + + "})()"); + } + }); + webView.loadUrl(imageUrl); // 加载网页 + WebView webView2 = findViewById(R.id.imageView2); + String imageUrl2 = "https://img.shields.io/badge/oppose-" + bad + "-red"; + webView2.setBackgroundColor(0x00000000); // 设置背景为透明 + webView2.setWebViewClient(new WebViewClient() { + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + // 注入JavaScript来设置网页背景为透明 + view.loadUrl("javascript:(function() { " + + "document.body.style.backgroundColor = 'transparent'; " + + "})()"); + } + }); + webView2.loadUrl(imageUrl2); // 加载网页 + + checkAndIntial(); + getContent(); + /** + * 定位 + */ + 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); + + + + } + @SuppressLint("MissingInflatedId") + private void getContent() { + MaterialButton button = findViewById(R.id.list); + button.setOnClickListener(v -> { + // 创建弹窗 + AlertDialog.Builder builder = new AlertDialog.Builder(PageActivity.this); + LayoutInflater inflater = getLayoutInflater(); + View dialogView = inflater.inflate(R.layout.dialog_reviews, null); + builder.setView(dialogView); + + // 获取弹窗中的视图 + RecyclerView recyclerViewReviews = dialogView.findViewById(R.id.recyclerViewReviews); + EditText editTextComment = dialogView.findViewById(R.id.editTextComment); + EditText usrName = dialogView.findViewById(R.id.userName); + MaterialButton buttonSubmit = dialogView.findViewById(R.id.buttonSubmit); + + // 获取评价数据 + fetchReviewsFromApi(reviews -> { + // 设置RecyclerView的适配器 + ReviewAdapter adapter = new ReviewAdapter(reviews); + recyclerViewReviews.setLayoutManager(new LinearLayoutManager(PageActivity.this)); + recyclerViewReviews.setAdapter(adapter); + + // 设置发表评论按钮的点击事件 + buttonSubmit.setOnClickListener(v1 -> { + String comment = editTextComment.getText().toString().trim(); + String userName = usrName.getText().toString().trim(); + if (!comment.isEmpty()) { + PlaceContent newReview = new PlaceContent(); + newReview.setUser_name(userName); // 可以替换为当前用户的名字 + newReview.setUser_content(comment); + newReview.setPlace_id(id); // 设置关联的place_id + newReview.setUsed(true); // 设置是否使用 + adapter.addReview(newReview); + editTextComment.setText(""); + sendReviewToServer(newReview); + // 可以在这里添加发送评论到服务器的逻辑 + } + }); + + // 显示弹窗 + AlertDialog dialog = builder.create(); + dialog.show(); + }); + }); + } + + private void sendReviewToServer(PlaceContent review) { + OkHttpClient client = new OkHttpClient(); + Gson gson = new Gson(); + String json = gson.toJson(review); + RequestBody body = RequestBody.create(json, MediaType.parse("application/json; charset=utf-8")); + + Request request = new Request.Builder() + .url("http://mai.godserver.cn:11451/api/mai/v1/placeContent") + .post(body) + .build(); + + client.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + e.printStackTrace(); + runOnUiThread(() -> { + Toast.makeText(PageActivity.this, "发送评论失败", Toast.LENGTH_SHORT).show(); + }); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + if (response.isSuccessful()) { + runOnUiThread(() -> { + Toast.makeText(PageActivity.this, "评论发送成功", Toast.LENGTH_SHORT).show(); + }); + } else { + runOnUiThread(() -> { + Toast.makeText(PageActivity.this, "发送评论失败", Toast.LENGTH_SHORT).show(); + }); + } + } + }); + } + + private void fetchReviewsFromApi(Consumer> callback) { + OkHttpClient client = new OkHttpClient(); + Log.d("TAG", "fetchReviewsFromApi: " + id); + Request request = new Request.Builder() + .url("http://mai.godserver.cn:11451/api/mai/v1/placeContent?id=" + id) + .build(); + + client.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + e.printStackTrace(); + runOnUiThread(() -> { + Toast.makeText(PageActivity.this, "获取评价失败", Toast.LENGTH_SHORT).show(); + callback.accept(new ArrayList<>()); + }); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + if (response.isSuccessful()) { + String responseData = response.body().string(); + Gson gson = new Gson(); + Type listType = new TypeToken>() {}.getType(); + List reviews = gson.fromJson(responseData, listType); + runOnUiThread(() -> callback.accept(reviews)); + } else { + runOnUiThread(() -> { + Toast.makeText(PageActivity.this, "获取评价失败", Toast.LENGTH_SHORT).show(); + callback.accept(new ArrayList<>()); + }); + } + } + }); + } + + + private void checkAndIntial() { + String androidId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID); + String url = "http://mai.godserver.cn:11451/api/mai/v1/check?androidId=" + androidId; + Request request = new Request.Builder() + .url(url) + .build(); + adminIt.setOnClickListener(v -> { + // 创建一个可以输入数量的弹窗,在点击确定后执行指定操作 + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(PageActivity.this); + LinearLayout layout = new LinearLayout(PageActivity.this); + layout.setOrientation(LinearLayout.VERTICAL); + layout.setPadding(16, 16, 16, 16); + +// 创建一个 ScrollView 并将 LinearLayout 添加到其中 + ScrollView scrollView = new ScrollView(PageActivity.this); + scrollView.addView(layout); + +// 创建店铺名称输入框及其标签 + TextView textNameLabel = new TextView(PageActivity.this); + textNameLabel.setText("店铺名称:"); + EditText textName = new EditText(PageActivity.this); + textName.setHint("请输入店铺名称"); + textName.setText(place.getName()); + layout.addView(textNameLabel); + layout.addView(textName); + +// 创建省份输入框及其标签 + TextView textProvinceLabel = new TextView(PageActivity.this); + textProvinceLabel.setText("省份:"); + EditText textProvince = new EditText(PageActivity.this); + textProvince.setHint("请输入省份"); + textProvince.setText(place.getProvince()); + layout.addView(textProvinceLabel); + layout.addView(textProvince); + +// 创建城市输入框及其标签 + TextView textCityLabel = new TextView(PageActivity.this); + textCityLabel.setText("城市:"); + EditText textCity = new EditText(PageActivity.this); + textCity.setHint("请输入城市"); + textCity.setText(place.getCity()); + layout.addView(textCityLabel); + layout.addView(textCity); + +// 创建地区输入框及其标签 + TextView textAreaLabel = new TextView(PageActivity.this); + textAreaLabel.setText("地区:"); + EditText textArea = new EditText(PageActivity.this); + textArea.setHint("请输入地区"); + textArea.setText(place.getArea()); + layout.addView(textAreaLabel); + layout.addView(textArea); + +// 创建地址输入框及其标签 + TextView textAddressLabel = new TextView(PageActivity.this); + textAddressLabel.setText("地址:"); + EditText textAddress = new EditText(PageActivity.this); + textAddress.setHint("请输入地址"); + textAddress.setText(place.getAddress()); + layout.addView(textAddressLabel); + layout.addView(textAddress); + +// 创建经度输入框及其标签 + TextView textXLabel = new TextView(PageActivity.this); + textXLabel.setText("经度:"); + EditText textX = new EditText(PageActivity.this); + textX.setHint("请输入经度"); + textX.setText(String.valueOf(place.getX())); + layout.addView(textXLabel); + layout.addView(textX); + +// 创建纬度输入框及其标签 + TextView textYLabel = new TextView(PageActivity.this); + textYLabel.setText("纬度:"); + EditText textY = new EditText(PageActivity.this); + textY.setHint("请输入纬度"); + textY.setText(String.valueOf(place.getY())); + layout.addView(textYLabel); + layout.addView(textY); + +// 创建国机数量输入框及其标签 + TextView textNumLabel = new TextView(PageActivity.this); + textNumLabel.setText("国机数量:"); + EditText textNum = new EditText(PageActivity.this); + textNum.setHint("请输入国机数量"); + textNum.setText(String.valueOf(place.getNum())); + layout.addView(textNumLabel); + layout.addView(textNum); + +// 创建币数量输入框及其标签 + TextView textNumJLabel = new TextView(PageActivity.this); + textNumJLabel.setText("日机数量:"); + EditText textNumJ = new EditText(PageActivity.this); + textNumJ.setHint("请输入日机数量"); + textNumJ.setText(String.valueOf(place.getNumJ())); + layout.addView(textNumJLabel); + layout.addView(textNumJ); + +// 创建是否使用输入框及其标签 + TextView textIsUseLabel = new TextView(PageActivity.this); + textIsUseLabel.setText("是否使用:"); + EditText textIsUse = new EditText(PageActivity.this); + textIsUse.setHint("请输入是否使用"); + textIsUse.setText(String.valueOf(place.getIsUse())); + layout.addView(textIsUseLabel); + layout.addView(textIsUse); + + builder.setTitle("编辑店铺信息") + .setView(scrollView) // 设置 ScrollView 作为对话框的内容视图 + .setPositiveButton("确定", (dialog, which) -> { + // 获取输入框的值并更新 place 对象 + place.setName(textName.getText().toString()); + place.setProvince(textProvince.getText().toString()); + place.setCity(textCity.getText().toString()); + place.setArea(textArea.getText().toString()); + place.setAddress(textAddress.getText().toString()); + place.setX(Double.parseDouble(textX.getText().toString())); + place.setY(Double.parseDouble(textY.getText().toString())); + place.setNum(Integer.parseInt(textNum.getText().toString())); + int num2 = 0; + try { + num2 = Integer.parseInt(textNumJ.getText().toString()); + } catch (NumberFormatException e) { + throw new RuntimeException(e); + } + place.setNumJ(num2); + place.setIsUse(Integer.parseInt(textIsUse.getText().toString())); + // 调用 sendUpdateNum 方法上传更新 + update(place); + }) + .setNegativeButton("取消", null) + .show(); + + }); + + + client.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + e.printStackTrace(); + adminIt.setVisibility(View.GONE); + } + @Override + public void onResponse(Call call, Response response) throws IOException { + if (response.isSuccessful()) { + final String responseData = response.body().string(); + runOnUiThread(() -> { + if(!responseData.equals("1")) { + adminIt.setVisibility(View.GONE); + Toast.makeText(PageActivity.this, "管理员", Toast.LENGTH_LONG).show(); + } + Log.d("TAG", "Response: " + responseData); + }); + } else { + adminIt.setVisibility(View.GONE); + } + } + }); + } + public void update(Place place) { + String androidId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID); + String url = "http://mai.godserver.cn:11451/api/mai/v1/place?androidId=" + androidId; + String json = new Gson().toJson(place); + RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), json); + Request request = new Request.Builder() + .url(url) + .post(requestBody) + .build(); + client.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + e.printStackTrace(); + runOnUiThread(() -> Toast.makeText(PageActivity.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); + Toast.makeText(PageActivity.this, "更改成功", Toast.LENGTH_SHORT).show(); + }); + } + runOnUiThread(() -> { + }); + } + }); + } + private void showNavigationOptions() { + final CharSequence[] items = {"Google Maps", "高德地图", "百度地图(暂时不可用)", "原生方法"}; + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("选择导航应用") + .setItems(items, (dialog, item) -> { + switch (item) { + case 0: + startGoogleMaps(); + break; + case 1: + startAmap(); + break; + case 2: + startBaiduMaps(); + break; + case 3: + startGeoIntent(); + } + }) + .show(); + } + + private void startGeoIntent(){ + String uri = "geo:" + tagXY[1] + "," + tagXY[0] + "?q=" + tagplace; + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri)); + startActivity(intent); + } + + 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", Uri.parse("androidamap://route?sourceApplication=appName&slat=&slon=&sname=我的位置&dlat=" + tagXY[1] +"&dlon="+ tagXY[0]+"&dname=" +tagplace + "&dev=0&t=2")); + PageActivity.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", Uri.parse(uri)); + startActivity(intent); + } + public static boolean isPackageInstalled(String packageName) { + return new File("\\Android\\data\\" + packageName).exists(); + } + private void showInstallAppDialog(String appName) { + new AlertDialog.Builder(this) + .setTitle("应用未安装") + .setMessage(appName + "尚未安装,是否前往应用商店下载?") + .setPositiveButton("确定", (dialog, which) -> { + Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getAppPackageName(appName))); + startActivity(marketIntent); + }) + .setNegativeButton("取消", null) + .show(); + } + + private String getAppPackageName(String appName) { + switch (appName) { + case "Google Maps": + return "com.google.android.apps.maps"; + case "高德地图": + return "com.autonavi.minimap"; + case "百度地图": + return "com.baidu.BaiduMap"; + default: + return ""; + } + } + @SuppressLint("StaticFieldLeak") + private void getNumberPeo() { + try { + new AsyncTask() { + @Override + protected String doInBackground(Void... voids) { + OkHttpClient client = new OkHttpClient(); + try { + String web = "http://www.godserver.cn:11451/api/mai/v1/placePeo?"; + // 将JSON对象转换为RequestBody + MediaType JSON = MediaType.get("application/json; charset=utf-8"); + @SuppressLint("StaticFieldLeak") Request request = new Request.Builder() + .url(web + "id=" + id) + .build(); + + try (Response response = client.newCall(request).execute()) { + if (((Response) response).isSuccessful()) { + return response.body().string(); + } else { + return "Error: " + response.code(); + } + } catch (Exception e) { + Log.e("OkHttp", "Error: " + e.getMessage()); + return "Error: " + e.getMessage(); + } + } catch (Exception e) { + return "BedWeb"; + } + } + + @Override + protected void onPostExecute(String result) { + try { + ApiResponse apiResponse = new Gson().fromJson(result, ApiResponse.class); + if (apiResponse.getStatus() == 200) { + numberPeo.setText("机厅预计人数:" + apiResponse.getMessage()); + } + }catch (Exception e) { + numberPeo.setText("无法预计"); + } + + } + }.execute(); + } catch (Exception e) { + Log.e("OkHttp", "Error: " + e.getMessage()); + } + } + @SuppressLint("StaticFieldLeak") + private void sendGetRequest(int type) { + AsyncTask asyncTask = new AsyncTask() { + @Override + protected String doInBackground(Void... voids) { + OkHttpClient client = new OkHttpClient(); + String web = "http://mai.godserver.cn:11451/api/" + type_code + "/v1/place?id=" + id + "&type=" + type; + System.out.println(web); + @SuppressLint("StaticFieldLeak") Request request = new Request.Builder() + .url(web) + .build(); + try (Response response = client.newCall(request).execute()) { + if (((Response) response).isSuccessful()) { + return response.body().string(); + } else { + return "Error: " + response.code(); + } + } catch (Exception e) { + Log.e("OkHttp", "Error: " + e.getMessage()); + Toast.makeText(PageActivity.this, "上传失败!", Toast.LENGTH_SHORT).show(); + return "Error: " + e.getMessage(); + } + } + + @Override + protected void onPostExecute(String result) { + if(result.equals("1")) { + Toast.makeText(PageActivity.this, "上传成功!", Toast.LENGTH_SHORT).show(); + Toast.makeText(PageActivity.this, "数据会在第二天刷新~", Toast.LENGTH_SHORT).show(); + } + } + }.execute(); + } + + @SuppressLint("StaticFieldLeak") + public void findnear(Place place_centor) { + new AsyncTask() { + @Override + protected String doInBackground(Void... voids) { + OkHttpClient client = new OkHttpClient(); + String web = "http://mai.godserver.cn:11451/api/" + type_code + "/v1/near?id=" + place_centor.getId(); + Log.d("Web", web); + @SuppressLint("StaticFieldLeak") Request request = new Request.Builder() + .url(web) + .build(); + + try (Response response = client.newCall(request).execute()) { + if (((Response) response).isSuccessful()) { + return response.body().string(); + } else { + return "Error: " + response.code(); + } + } catch (Exception e) { + Log.e("OkHttp", "Error: " + e.getMessage()); + return "Error: " + e.getMessage(); + } + } + + @SuppressLint({"StaticFieldLeak", "SetTextI18n"}) + @Override + protected void onPostExecute(String result) { + if (result.contains("[{")) { + marketList = parseJsonToPlaceList2(result); + Toast.makeText(PageActivity.context, "数据获取成功"+ result, Toast.LENGTH_SHORT); + for (Market market : marketList) { + Log.d("Market", market.getMarketName()); + } + for (int i = 0; i < marketList.size(); i++) { + TextView t = new TextView(PageActivity.context); + t.setTextColor(ContextCompat.getColor(PageActivity.context, R.color.textcolorPrimary)); + + double distance = marketList.get(i).getDistance(); + int type = marketList.get(i).getType(); + DecimalFormat decimalFormat = new DecimalFormat("0.#"); + String formattedResult = decimalFormat.format(distance*1000); + if(type==1) { + t.setTextColor(Color.rgb(255, 182, 193)); + }else if(type==2) { + t.setTextColor(Color.rgb(144, 238, 144)); + } + t.setText(marketList.get(i).getMarketName() + " \n距离机厅:" + distance + "米\n"); + t.setTextSize(15.0F); + int finalI = i; + t.isTextSelectable(); + t.isEnabled(); + t.setOnClickListener(v -> { + tagXY[0] = marketList.get(finalI).getX(); + tagXY[1] = marketList.get(finalI).getY(); + + tagplace = marketList.get(finalI).getMarketName().split(" ")[0]; + //导航 + Toast.makeText(PageActivity.context, "即将导航" + marketList.get(finalI).getMarketName(), Toast.LENGTH_SHORT).show(); + showNavigationOptions(); + }); + textViews.add(t); + t31.addView(t); + } + }else { + TextView ttt =new TextView(PageActivity.context); + ttt.setText("暂时关闭\n\n\n\n\n\n\n\n"); + ttt.setTextColor(ContextCompat.getColor(PageActivity.context, R.color.textcolorPrimary)); + + t31.addView(ttt); + } + } + }.execute(); + } + @SuppressLint("StaticFieldLeak") + private void sendUpdateNum(int id,int num,int numJ) { + AsyncTask asyncTask = new AsyncTask() { + @Override + protected String doInBackground(Void... voids) { + OkHttpClient client = new OkHttpClient(); + String web = "http://mai.godserver.cn:11451/api/" + type_code + "/v1/num?id=" + id + "&num=" + num + "&numJ=" + numJ; + Log.d("Web", numJ + ""); + @SuppressLint("StaticFieldLeak") Request request = new Request.Builder() + .url(web) + .build(); + try (Response response = client.newCall(request).execute()) { + if (((Response) response).isSuccessful()) { + return response.body().string(); + } else { + return "Error: " + response.code(); + } + } catch (Exception e) { + Log.e("OkHttp", "Error: " + e.getMessage()); + Toast.makeText(PageActivity.this, "上传失败!", Toast.LENGTH_SHORT).show(); + return "Error: " + e.getMessage(); + } + } + + @Override + protected void onPostExecute(String result) { + if(result.equals("1")) { + Toast.makeText(PageActivity.this, "上传成功!", Toast.LENGTH_SHORT).show(); + Toast.makeText(PageActivity.this, "机厅数据更新,重启软件后即可在主界面生效", Toast.LENGTH_SHORT).show(); + TextView num1 = findViewById(R.id.num5); + num1.setText("舞萌机台 "+num); + AlertDialog.Builder ne = new AlertDialog.Builder(PageActivity.this); + ne.setTitle("重启软件即可生效") + .setPositiveButton("重启", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName()); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + finish(); + } + }) + .setNegativeButton("不重启", null) + .show(); + } + } + }.execute(); + } + private static List parseJsonToPlaceList2(String jsonString) { + Gson gson = new Gson(); + Type placeListType = new TypeToken>() { + }.getType(); + return gson.fromJson(jsonString, placeListType); + } + + private void startLikeAnimation(MaterialButton button) { + // 缩放动画 + ObjectAnimator scaleOutX = ObjectAnimator.ofFloat(button, "scaleX", 1f, 1.5f); + ObjectAnimator scaleOutY = ObjectAnimator.ofFloat(button, "scaleY", 1f, 1.5f); + ObjectAnimator scaleInX = ObjectAnimator.ofFloat(button, "scaleX", 1.5f, 1f); + ObjectAnimator scaleInY = ObjectAnimator.ofFloat(button, "scaleY", 1.5f, 1f); + + // 晃动动画 + ObjectAnimator shake1 = ObjectAnimator.ofFloat(button, "rotation", 0f, -5f); + ObjectAnimator shake2 = ObjectAnimator.ofFloat(button, "rotation", -5f, 5f); + ObjectAnimator shake3 = ObjectAnimator.ofFloat(button, "rotation", 5f, -3f); + ObjectAnimator shake4 = ObjectAnimator.ofFloat(button, "rotation", -3f, 0f); + + // 颜色变化动画 + ObjectAnimator colorAnim = ObjectAnimator.ofInt(button, "backgroundColor", Color.BLACK, Color.RED); + colorAnim.setEvaluator(new ArgbEvaluator()); + + // 组合动画 + AnimatorSet animatorSet = new AnimatorSet(); + animatorSet.playTogether(scaleOutX, scaleOutY, shake1, shake2, shake3, shake4); + animatorSet.play(scaleInX).with(scaleInY).after(shake4); + animatorSet.play(colorAnim).with(scaleInX); + + animatorSet.setDuration(300); + animatorSet.start(); + } + private void startShakeAnimation(MaterialButton button) { + // 晃动动画 + ObjectAnimator shake1 = ObjectAnimator.ofFloat(button, "rotation", 0f, -5f); + ObjectAnimator shake2 = ObjectAnimator.ofFloat(button, "rotation", -5f, 5f); + ObjectAnimator shake3 = ObjectAnimator.ofFloat(button, "rotation", 5f, -3f); + ObjectAnimator shake4 = ObjectAnimator.ofFloat(button, "rotation", -3f, 0f); + + // 组合动画 + AnimatorSet animatorSet = new AnimatorSet(); + animatorSet.playSequentially(shake1, shake2, shake3, shake4); + + animatorSet.setDuration(300); + animatorSet.start(); + } + private void backAnimation(MaterialButton button) { + // 颜色变化动画 + ObjectAnimator colorAnim = ObjectAnimator.ofInt(button, "backgroundColor", Color.RED, Color.BLACK); + colorAnim.setEvaluator(new ArgbEvaluator()); + + // 组合动画 + AnimatorSet animatorSet = new AnimatorSet(); + animatorSet.play(colorAnim); + + animatorSet.setDuration(300); + animatorSet.start(); + } + + private class SendMarketRequestTask extends AsyncTask { + + @Override + protected String doInBackground(Market... markets) { + Market market = markets[0]; + + // 使用 Gson 将 Market 对象转换为 JSON 字符串 + Gson gson = new Gson(); + String json = gson.toJson(market); + + // 创建 OkHttpClient 实例 + OkHttpClient client = new OkHttpClient(); + + // 创建请求体 + RequestBody body = RequestBody.create(json, MediaType.parse("application/json; charset=utf-8")); + + // 创建请求 + Request request = new Request.Builder() + .url("http://mai.godserver.cn:11451/api/" + type_code + "/v1/near") + .post(body) + .build(); + + try { + // 发送请求 + Response response = client.newCall(request).execute(); + if (response.isSuccessful()) { + return response.body().string(); + } else { + return "Request failed: " + response.code(); + } + } catch (IOException e) { + e.printStackTrace(); + return "Request failed: " + e.getMessage(); + } + } + + @Override + protected void onPostExecute(String result) { + Log.d("TAG", "Response: " + result); + } + } + private void openLinkHub(String meituan,String douyin) { + final Context context = this; + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("选择链接") + + .setItems(new String[]{"美团:" + meituan, "抖音:" + douyin}, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (i == 0) { + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("link", meituan); + clipboard.setPrimaryClip(clip); + Toast.makeText(PageActivity.this, "已复制链接,请在美团中粘贴并打开", Toast.LENGTH_SHORT).show(); + }else { + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("link", douyin); + clipboard.setPrimaryClip(clip); + Toast.makeText(PageActivity.this, "已复制链接,请在抖音中粘贴并打开", Toast.LENGTH_SHORT).show(); + } + } + }) + .setPositiveButton("更新链接(null就是不存在)", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + // 创建一个输入框的 Dialog + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle("编辑链接"); + + // 创建一个 LinearLayout 来包含两个 EditText + LinearLayout layout = new LinearLayout(context); + layout.setOrientation(LinearLayout.VERTICAL); + layout.setPadding(16, 16, 16, 16); + + // 创建美团链接的 EditText + EditText meituanEditText = new EditText(context); + meituanEditText.setHint("美团链接(店铺点击复制链接即可)"); + meituanEditText.setText(meituan); // 设置默认值 + layout.addView(meituanEditText); + + // 创建抖音链接的 EditText + EditText douyinEditText = new EditText(context); + douyinEditText.setHint("抖音链接(团购点击复制链接即可)"); + douyinEditText.setText(douyin); // 设置默认值 + layout.addView(douyinEditText); + + // 设置对话框的视图 + builder.setView(layout); + + // 添加确定按钮 + builder.setPositiveButton("确定", (dialog, which) -> { + // 获取用户输入的美团和抖音链接 + String newMeituanLink = meituanEditText.getText().toString(); + String newDouyinLink = douyinEditText.getText().toString(); + + sendUpdateLink(id,newMeituanLink,newDouyinLink); + // 调用回调函数 + }); + + // 添加取消按钮 + builder.setNegativeButton("取消", (dialog, which) -> dialog.dismiss()); + + // 创建并显示对话框 + AlertDialog dialog = builder.create(); + dialog.show(); + } + }) + .setNegativeButton("取消", null) + .show(); + } + private void sendUpdateLink(int id,String meituan,String douyin) { + this.meituan = meituan; + this.douyin = douyin; + RequestBody body = RequestBody.create(meituan, MediaType.parse("application/json; charset=utf-8")); + Request request = new Request.Builder() + .url("http://mai.godserver.cn:11451/api/" + type_code + "/v1/updateLink?id=" + id + "&meituan=" + meituan + "&douyin=" + douyin) + .post(body) + .build(); + Log.d("url",("http://mai.godserver.cn:11451/api/" + type_code + "/v1/updateLink?id=" + id + "&meituan=" + meituan + "&douyin=" + douyin)); + client.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + Toast.makeText(PageActivity.this, "更新失败", Toast.LENGTH_SHORT).show(); + e.printStackTrace(); + } + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { + if (response.isSuccessful()) { + String responseBody = response.body().string(); + Log.d("TAG", "Response: " + responseBody); + runOnUiThread(() -> { + Toast.makeText(PageActivity.this, "更新成功", Toast.LENGTH_SHORT).show(); + }); + } + } + }); + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/gallery/GalleryFragment.java b/app/src/main/java/org/astral/findmaimaiultra/ui/gallery/GalleryFragment.java new file mode 100644 index 0000000..169b876 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/ui/gallery/GalleryFragment.java @@ -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 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; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/gallery/GalleryViewModel.java b/app/src/main/java/org/astral/findmaimaiultra/ui/gallery/GalleryViewModel.java new file mode 100644 index 0000000..c1bbf4b --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/ui/gallery/GalleryViewModel.java @@ -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 mText; + + public GalleryViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("This is gallery fragment"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/home/HomeFragment.java b/app/src/main/java/org/astral/findmaimaiultra/ui/home/HomeFragment.java new file mode 100644 index 0000000..1d10a4b --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/ui/home/HomeFragment.java @@ -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 marketList = new ArrayList<>(); + private Context context; + public static String province; + public static String city; + public static List a = new ArrayList<>(); + public static List b = new ArrayList<>(); + private BroadcastReceiver locationReceiver; + public static List 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 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 places = parseJsonToPlaceList(result); + if (places != null) { + updateUI(places); + } + } else { + showNetworkErrorToast("网络错误(服务器维护)"); + } + } else { + showNetworkErrorToast( "致命错误,服务器未启动"); + } + } + }); + } + + private void updateUI(List 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 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 parseJsonToPlaceList(String jsonString) { + Gson gson = new Gson(); + Type placeListType = new TypeToken>() { + }.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 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 parseJsonToGeocodeList(String jsonString) { + Gson gson = new Gson(); + JsonArray jsonArray = gson.fromJson(jsonString, JsonArray.class); + List 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 parseJsonToPlaceList2(String jsonString) { + Gson gson = new Gson(); + Type placeListType = new TypeToken>() { + }.getType(); + return gson.fromJson(jsonString, placeListType); + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/home/HomeViewModel.java b/app/src/main/java/org/astral/findmaimaiultra/ui/home/HomeViewModel.java new file mode 100644 index 0000000..991afb6 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/ui/home/HomeViewModel.java @@ -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 mText; + + public HomeViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("This is home fragment"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/slideshow/SlideshowFragment.java b/app/src/main/java/org/astral/findmaimaiultra/ui/slideshow/SlideshowFragment.java new file mode 100644 index 0000000..f5b3b62 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/ui/slideshow/SlideshowFragment.java @@ -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 call = service.getLatestRelease("Spaso1", "FindMaimaiDX_Phone"); // 替换为你的仓库信息 + + call.enqueue(new Callback() { + @SuppressLint("SetTextI18n") + @Override + public void onResponse(@NonNull Call call, @NonNull Response 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 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; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/slideshow/SlideshowViewModel.java b/app/src/main/java/org/astral/findmaimaiultra/ui/slideshow/SlideshowViewModel.java new file mode 100644 index 0000000..b345bdd --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/ui/slideshow/SlideshowViewModel.java @@ -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 mText; + + public SlideshowViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("This is slideshow fragment"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/astral/findmaimaiultra/utill/AddressParser.java b/app/src/main/java/org/astral/findmaimaiultra/utill/AddressParser.java new file mode 100644 index 0000000..6a5e63a --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/utill/AddressParser.java @@ -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 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) { + } + + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/utill/DeviceInfoUtils.java b/app/src/main/java/org/astral/findmaimaiultra/utill/DeviceInfoUtils.java new file mode 100644 index 0000000..0ae96a9 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/utill/DeviceInfoUtils.java @@ -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(); + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/utill/GitHubApiClient.java b/app/src/main/java/org/astral/findmaimaiultra/utill/GitHubApiClient.java new file mode 100644 index 0000000..e8c6424 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/utill/GitHubApiClient.java @@ -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); + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/utill/NetworkUtils.java b/app/src/main/java/org/astral/findmaimaiultra/utill/NetworkUtils.java new file mode 100644 index 0000000..086a7be --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/utill/NetworkUtils.java @@ -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 parseChartPlays(String responseBody) throws JSONException { + List 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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/utill/SharedViewModel.java b/app/src/main/java/org/astral/findmaimaiultra/utill/SharedViewModel.java new file mode 100644 index 0000000..2d17a16 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/utill/SharedViewModel.java @@ -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> sharedMap = new MutableLiveData<>(); + private final MutableLiveData> placelist = new MutableLiveData<>(); + + + public SharedViewModel() { + placelist.setValue(null); + sharedMap.setValue(new HashMap<>()); + } + public MutableLiveData> getPlacelist() { + return placelist; + } + public MutableLiveData> getSharedMap() { + return sharedMap; + } + + public void addToMap(String key, String value) { + Map currentMap = sharedMap.getValue(); + if (currentMap != null) { + currentMap.put(key, value); + sharedMap.setValue(currentMap); + } + } + + public void removeFromMap(String key) { + Map currentMap = sharedMap.getValue(); + if (currentMap != null) { + currentMap.remove(key); + sharedMap.setValue(currentMap); + } + } + public void setPlacelist(ArrayList placelist) { + this.placelist.setValue(placelist); + } + public void clearMap() { + sharedMap.setValue(new HashMap<>()); + } + public void clearPlacelist() { + placelist.setValue(null); + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/utill/Shuiyu2Luoxue.java b/app/src/main/java/org/astral/findmaimaiultra/utill/Shuiyu2Luoxue.java new file mode 100644 index 0000000..0fca792 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/utill/Shuiyu2Luoxue.java @@ -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 shuiyu2luoxue(PlayerData playerData) { + ArrayList 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; + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/utill/UriToFileConverter.java b/app/src/main/java/org/astral/findmaimaiultra/utill/UriToFileConverter.java new file mode 100644 index 0000000..5afa6dc --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/utill/UriToFileConverter.java @@ -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()); + } +} diff --git a/app/src/main/java/org/astral/findmaimaiultra/utill/ZoomableViewGroup.java b/app/src/main/java/org/astral/findmaimaiultra/utill/ZoomableViewGroup.java new file mode 100644 index 0000000..b3cfd68 --- /dev/null +++ b/app/src/main/java/org/astral/findmaimaiultra/utill/ZoomableViewGroup.java @@ -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); + } +} diff --git a/app/src/main/res/####values-night/colors.xml b/app/src/main/res/####values-night/colors.xml new file mode 100644 index 0000000..5fe2644 --- /dev/null +++ b/app/src/main/res/####values-night/colors.xml @@ -0,0 +1,31 @@ + + + #673AB7 + #673AB7 + #FF3700B3 + #045D53 + #673AB7 + #FFFFFF + + #FF018786 + #8A8282 + #FFFFFFFF + #673AB7 + #673AB7 + #673AB7 + #3F51B5 + #212121 + #727272 + #FFFFFF + #B6B6B6 + #673AB7 + #673AB7 + #141313 + #045D53 + #018786 + #000000 + #045D53 + #C2F6C4 + #FFFFFF + #F44336 + \ No newline at end of file diff --git a/app/src/main/res/####values-night/styles.xml b/app/src/main/res/####values-night/styles.xml new file mode 100644 index 0000000..6f38fbc --- /dev/null +++ b/app/src/main/res/####values-night/styles.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/app/src/main/res/####values-night/themes.xml b/app/src/main/res/####values-night/themes.xml new file mode 100644 index 0000000..edb67f9 --- /dev/null +++ b/app/src/main/res/####values-night/themes.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/border.xml b/app/src/main/res/drawable/border.xml new file mode 100644 index 0000000..a86a375 --- /dev/null +++ b/app/src/main/res/drawable/border.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/res/drawable/bot_message_background.xml b/app/src/main/res/drawable/bot_message_background.xml new file mode 100644 index 0000000..6de43c4 --- /dev/null +++ b/app/src/main/res/drawable/bot_message_background.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/button_background.xml b/app/src/main/res/drawable/button_background.xml new file mode 100644 index 0000000..fd0e0b3 --- /dev/null +++ b/app/src/main/res/drawable/button_background.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/dx.png b/app/src/main/res/drawable/dx.png new file mode 100644 index 0000000..8af5543 Binary files /dev/null and b/app/src/main/res/drawable/dx.png differ diff --git a/app/src/main/res/drawable/edit_text_background.xml b/app/src/main/res/drawable/edit_text_background.xml new file mode 100644 index 0000000..38e2fd3 --- /dev/null +++ b/app/src/main/res/drawable/edit_text_background.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/edittext_background.xml b/app/src/main/res/drawable/edittext_background.xml new file mode 100644 index 0000000..43acac2 --- /dev/null +++ b/app/src/main/res/drawable/edittext_background.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/fcfs.png b/app/src/main/res/drawable/fcfs.png new file mode 100644 index 0000000..804f1c5 Binary files /dev/null and b/app/src/main/res/drawable/fcfs.png differ diff --git a/app/src/main/res/drawable/ic_launcher.png b/app/src/main/res/drawable/ic_launcher.png new file mode 100644 index 0000000..71d1c53 Binary files /dev/null and b/app/src/main/res/drawable/ic_launcher.png differ diff --git a/app/src/main/res/drawable/ic_launcher2.png b/app/src/main/res/drawable/ic_launcher2.png new file mode 100644 index 0000000..f6b22d1 Binary files /dev/null and b/app/src/main/res/drawable/ic_launcher2.png differ diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..956b344 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..1ee1493 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_menu_camera.xml b/app/src/main/res/drawable/ic_menu_camera.xml new file mode 100644 index 0000000..41688d5 --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_camera.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_menu_gallery.xml b/app/src/main/res/drawable/ic_menu_gallery.xml new file mode 100644 index 0000000..ff8ce52 --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_gallery.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_menu_slideshow.xml b/app/src/main/res/drawable/ic_menu_slideshow.xml new file mode 100644 index 0000000..ae51e49 --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_slideshow.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/id_add.xml b/app/src/main/res/drawable/id_add.xml new file mode 100644 index 0000000..28b245a --- /dev/null +++ b/app/src/main/res/drawable/id_add.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/input_background.xml b/app/src/main/res/drawable/input_background.xml new file mode 100644 index 0000000..edaece3 --- /dev/null +++ b/app/src/main/res/drawable/input_background.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/link_background.xml b/app/src/main/res/drawable/link_background.xml new file mode 100644 index 0000000..fc1412f --- /dev/null +++ b/app/src/main/res/drawable/link_background.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/logo.png b/app/src/main/res/drawable/logo.png new file mode 100644 index 0000000..7903a0a Binary files /dev/null and b/app/src/main/res/drawable/logo.png differ diff --git a/app/src/main/res/drawable/placeholder.jpg b/app/src/main/res/drawable/placeholder.jpg new file mode 100644 index 0000000..586194b Binary files /dev/null and b/app/src/main/res/drawable/placeholder.jpg differ diff --git a/app/src/main/res/drawable/rank_a.png b/app/src/main/res/drawable/rank_a.png new file mode 100644 index 0000000..32f2eff Binary files /dev/null and b/app/src/main/res/drawable/rank_a.png differ diff --git a/app/src/main/res/drawable/rank_aa.png b/app/src/main/res/drawable/rank_aa.png new file mode 100644 index 0000000..a0fde15 Binary files /dev/null and b/app/src/main/res/drawable/rank_aa.png differ diff --git a/app/src/main/res/drawable/rank_aaa.png b/app/src/main/res/drawable/rank_aaa.png new file mode 100644 index 0000000..8eb3b0e Binary files /dev/null and b/app/src/main/res/drawable/rank_aaa.png differ diff --git a/app/src/main/res/drawable/rank_b.png b/app/src/main/res/drawable/rank_b.png new file mode 100644 index 0000000..f740b38 Binary files /dev/null and b/app/src/main/res/drawable/rank_b.png differ diff --git a/app/src/main/res/drawable/rank_bb.png b/app/src/main/res/drawable/rank_bb.png new file mode 100644 index 0000000..ed78be7 Binary files /dev/null and b/app/src/main/res/drawable/rank_bb.png differ diff --git a/app/src/main/res/drawable/rank_bbb.png b/app/src/main/res/drawable/rank_bbb.png new file mode 100644 index 0000000..1abc4ac Binary files /dev/null and b/app/src/main/res/drawable/rank_bbb.png differ diff --git a/app/src/main/res/drawable/rank_c.png b/app/src/main/res/drawable/rank_c.png new file mode 100644 index 0000000..268ce7a Binary files /dev/null and b/app/src/main/res/drawable/rank_c.png differ diff --git a/app/src/main/res/drawable/rank_d.png b/app/src/main/res/drawable/rank_d.png new file mode 100644 index 0000000..06f02b1 Binary files /dev/null and b/app/src/main/res/drawable/rank_d.png differ diff --git a/app/src/main/res/drawable/rank_s.png b/app/src/main/res/drawable/rank_s.png new file mode 100644 index 0000000..fc21437 Binary files /dev/null and b/app/src/main/res/drawable/rank_s.png differ diff --git a/app/src/main/res/drawable/rank_sp.png b/app/src/main/res/drawable/rank_sp.png new file mode 100644 index 0000000..dfc93ec Binary files /dev/null and b/app/src/main/res/drawable/rank_sp.png differ diff --git a/app/src/main/res/drawable/rank_ss.png b/app/src/main/res/drawable/rank_ss.png new file mode 100644 index 0000000..4aed0e6 Binary files /dev/null and b/app/src/main/res/drawable/rank_ss.png differ diff --git a/app/src/main/res/drawable/rank_ssp.png b/app/src/main/res/drawable/rank_ssp.png new file mode 100644 index 0000000..16c2619 Binary files /dev/null and b/app/src/main/res/drawable/rank_ssp.png differ diff --git a/app/src/main/res/drawable/rank_sss.png b/app/src/main/res/drawable/rank_sss.png new file mode 100644 index 0000000..2d6f91a Binary files /dev/null and b/app/src/main/res/drawable/rank_sss.png differ diff --git a/app/src/main/res/drawable/rank_sssp.png b/app/src/main/res/drawable/rank_sssp.png new file mode 100644 index 0000000..bda8bc8 Binary files /dev/null and b/app/src/main/res/drawable/rank_sssp.png differ diff --git a/app/src/main/res/drawable/rounded_background1.xml b/app/src/main/res/drawable/rounded_background1.xml new file mode 100644 index 0000000..a05e6a4 --- /dev/null +++ b/app/src/main/res/drawable/rounded_background1.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/rounded_background2.xml b/app/src/main/res/drawable/rounded_background2.xml new file mode 100644 index 0000000..0068fb2 --- /dev/null +++ b/app/src/main/res/drawable/rounded_background2.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/rounded_background3.xml b/app/src/main/res/drawable/rounded_background3.xml new file mode 100644 index 0000000..cd67c48 --- /dev/null +++ b/app/src/main/res/drawable/rounded_background3.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/rounded_background4.xml b/app/src/main/res/drawable/rounded_background4.xml new file mode 100644 index 0000000..107d954 --- /dev/null +++ b/app/src/main/res/drawable/rounded_background4.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/rounded_background5.xml b/app/src/main/res/drawable/rounded_background5.xml new file mode 100644 index 0000000..2348f72 --- /dev/null +++ b/app/src/main/res/drawable/rounded_background5.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/rounded_image.xml b/app/src/main/res/drawable/rounded_image.xml new file mode 100644 index 0000000..fd4138f --- /dev/null +++ b/app/src/main/res/drawable/rounded_image.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/app/src/main/res/drawable/sd.png b/app/src/main/res/drawable/sd.png new file mode 100644 index 0000000..5dd3e54 Binary files /dev/null and b/app/src/main/res/drawable/sd.png differ diff --git a/app/src/main/res/drawable/sd2.png b/app/src/main/res/drawable/sd2.png new file mode 100644 index 0000000..4ac4f99 Binary files /dev/null and b/app/src/main/res/drawable/sd2.png differ diff --git a/app/src/main/res/drawable/side_nav_bar.xml b/app/src/main/res/drawable/side_nav_bar.xml new file mode 100644 index 0000000..c47562e --- /dev/null +++ b/app/src/main/res/drawable/side_nav_bar.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/title2.png b/app/src/main/res/drawable/title2.png new file mode 100644 index 0000000..25b4f0e Binary files /dev/null and b/app/src/main/res/drawable/title2.png differ diff --git a/app/src/main/res/drawable/user_message_background.xml b/app/src/main/res/drawable/user_message_background.xml new file mode 100644 index 0000000..d61fbb3 --- /dev/null +++ b/app/src/main/res/drawable/user_message_background.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/vertical_line_glow.xml b/app/src/main/res/drawable/vertical_line_glow.xml new file mode 100644 index 0000000..4298c52 --- /dev/null +++ b/app/src/main/res/drawable/vertical_line_glow.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_hack_get_user_id.xml b/app/src/main/res/layout/activity_hack_get_user_id.xml new file mode 100644 index 0000000..c7bdbb2 --- /dev/null +++ b/app/src/main/res/layout/activity_hack_get_user_id.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..6882bb5 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,26 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_page.xml b/app/src/main/res/layout/activity_page.xml new file mode 100644 index 0000000..97cef21 --- /dev/null +++ b/app/src/main/res/layout/activity_page.xml @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/app_bar_main.xml b/app/src/main/res/layout/app_bar_main.xml new file mode 100644 index 0000000..7cf9556 --- /dev/null +++ b/app/src/main/res/layout/app_bar_main.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml new file mode 100644 index 0000000..a3a498e --- /dev/null +++ b/app/src/main/res/layout/content_main.xml @@ -0,0 +1,22 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_reviews.xml b/app/src/main/res/layout/dialog_reviews.xml new file mode 100644 index 0000000..aaec19f --- /dev/null +++ b/app/src/main/res/layout/dialog_reviews.xml @@ -0,0 +1,27 @@ + + + + + + +