diff --git a/app/build.gradle b/app/build.gradle
index b19d11e..ce04a26 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -11,7 +11,7 @@ android {
minSdk 29
targetSdk 34
versionCode 1
- versionName "1.6.1 b"
+ versionName "1.6.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 2a3693d..de5bee7 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -44,6 +44,8 @@
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
\ No newline at end of file
+
diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/JMActivity.java b/app/src/main/java/org/astral/findmaimaiultra/ui/JMActivity.java
index 949d90f..0609ca6 100644
--- a/app/src/main/java/org/astral/findmaimaiultra/ui/JMActivity.java
+++ b/app/src/main/java/org/astral/findmaimaiultra/ui/JMActivity.java
@@ -1,33 +1,55 @@
package org.astral.findmaimaiultra.ui;
+import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
+import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.request.target.CustomTarget;
+import com.bumptech.glide.request.transition.Transition;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
+import com.google.android.material.button.MaterialButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.gson.Gson;
import org.astral.findmaimaiultra.R;
import org.astral.findmaimaiultra.adapter.PhotoAdapter;
import org.astral.findmaimaiultra.been.pixiv.jm.Album;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
public class JMActivity extends AppCompatActivity {
private FrameLayout overlay;
private boolean isOverlayVisible = false;
private BottomSheetBehavior bottomSheetBehavior;
private PhotoAdapter photoAdapter;
+ private static final int REQUEST_CODE_WRITE_EXTERNAL_STORAGE = 1;
+ private Album album;
@Override
@SuppressLint("MissingInflatedId")
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -36,18 +58,19 @@ public class JMActivity extends AppCompatActivity {
initRecyclerView();
}
-
@SuppressLint({"ClickableViewAccessibility", "SetTextI18n", "ResourceType"})
private void initRecyclerView() {
Intent intent = getIntent();
String res = intent.getStringExtra("album");
Album a = new Gson().fromJson(res, Album.class);
+ album = a;
Toast.makeText(this,"加载中", Toast.LENGTH_SHORT).show();
RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
photoAdapter = new PhotoAdapter(this, a.getImage_urls(), a.getNums(), a);
photoAdapter.clearLoad();
-
+ MaterialButton downloadButton = findViewById(R.id.download);
+ downloadButton.setOnClickListener(v -> downloadAllImages());
recyclerView.setAdapter(photoAdapter);
bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottom_sheet));
bottomSheetBehavior.setPeekHeight(dpToPx(80));
@@ -59,6 +82,67 @@ public class JMActivity extends AppCompatActivity {
+ " \n " + a.getTags().toString().replaceAll( "\"","") .replaceAll( "\\[","").replaceAll( "]","")
+ " \n " + a.getAlbum_id().replaceAll( "\"","").replaceAll( "\\[","").replaceAll( "]",""));
}
+
+ private void downloadAllImages() {
+ String folderName = album.getName();
+ File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS + File.separator + "findmaimaiultra"), folderName);
+ int totalImages = photoAdapter.getItemCount();
+ int[] downloadedCount = {0}; // 使用数组来保存下载计数,以便在匿名内部类中修改
+
+ Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "Download started", Snackbar.LENGTH_INDEFINITE);
+ snackbar.show();
+ for (int i = 0; i < album.getImage_urls().size(); i++) {
+ String imageUrl = album.getImage_urls().get(i);
+ int num = album.getNums().get(i);
+ String FileName = "image_" + album.getAlbum_id() + "_" + i + ".jpg";
+ File file = new File(folder, FileName);
+ if (!folder.exists()) {
+ if (!folder.mkdirs()) {
+ Toast.makeText(this, "Failed to create folder", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ }
+
+ Glide.with(this)
+ .asBitmap()
+ .load(imageUrl)
+ .into(new CustomTarget() {
+ @Override
+ public void onResourceReady(@NonNull Bitmap resource, Transition super Bitmap> transition) {
+ Bitmap decodedBitmap = decodeImage(resource, num);
+ downloadedCount[0]++;
+ updateSnackBar(snackbar, downloadedCount[0], totalImages);
+ saveBitmapToFile(decodedBitmap, file);
+ }
+
+ @Override
+ public void onLoadCleared(Drawable placeholder) {
+ }
+
+ @Override
+ public void onLoadFailed(@Nullable Drawable errorDrawable) {
+ super.onLoadFailed(errorDrawable);
+ downloadedCount[0]++;
+ updateSnackBar(snackbar, downloadedCount[0], totalImages);
+ }
+ });
+ }
+ snackbar.setText("下载完成!保存在/Download/FindMaimaiUltra/本子名称 目录");
+ snackbar.setDuration(Snackbar.LENGTH_INDEFINITE);
+ snackbar.setAction("OK", v -> snackbar.dismiss());
+ Snackbar.make(findViewById(android.R.id.content), "下载完成!保存在/Download/FindMaimaiUltra/本子名称 目录", Snackbar.LENGTH_INDEFINITE)
+ .setAction("OK", v -> {
+ // 处理 Snackbar 按钮点击事件
+ })
+ .show();
+ }
+ private void updateSnackBar(Snackbar snackbar, int current, int total) {
+ String message = "Downloaded " + current + "/" + total + " images";
+ snackbar.setText(message);
+ if (current == total) {
+ snackbar.dismiss();
+ }
+ }
public int dpToPx(int dp) {
return (int) (dp * getResources().getDisplayMetrics().density);
}
@@ -69,4 +153,54 @@ public class JMActivity extends AppCompatActivity {
photoAdapter.clearCache();
}
}
+ private void saveBitmapToFile(Bitmap bitmap, File file) {
+ OutputStream outputStream = null;
+ try {
+ outputStream = new FileOutputStream(file);
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
+ } catch (Exception e) {
+ e.printStackTrace();
+ Toast.makeText(this, "Failed to save image", Toast.LENGTH_SHORT).show();
+ } finally {
+ if (outputStream != null) {
+ try {
+ outputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ private Bitmap decodeImage(Bitmap imgSrc, int num) {
+ if (num == 0) {
+ return imgSrc;
+ }
+
+ int w = imgSrc.getWidth();
+ int h = imgSrc.getHeight();
+
+ // 创建新的解密图片
+ Bitmap imgDecode = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(imgDecode);
+
+ int over = h % num;
+ for (int i = 0; i < num; i++) {
+ int move = h / num;
+ int ySrc = h - (move * (i + 1)) - over;
+ int yDst = move * i;
+
+ if (i == 0) {
+ move += over;
+ } else {
+ yDst += over;
+ }
+
+ Rect srcRect = new Rect(0, ySrc, w, ySrc + move);
+ Rect dstRect = new Rect(0, yDst, w, yDst + move);
+
+ canvas.drawBitmap(imgSrc, srcRect, dstRect, null);
+ }
+
+ return imgDecode;
+ }
}
diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/LinkQQBot.java b/app/src/main/java/org/astral/findmaimaiultra/ui/LinkQQBot.java
index d4d047a..626aaed 100644
--- a/app/src/main/java/org/astral/findmaimaiultra/ui/LinkQQBot.java
+++ b/app/src/main/java/org/astral/findmaimaiultra/ui/LinkQQBot.java
@@ -22,7 +22,9 @@ 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.UserData;
import org.astral.findmaimaiultra.been.faker.UserRegion;
+import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.Collections;
@@ -158,6 +160,7 @@ public class LinkQQBot extends AppCompatActivity {
Toast.makeText(LinkQQBot.this, "设置已保存,您的UsrId已写入硬盘!", Toast.LENGTH_SHORT).show();
try {
getUserRegionData(responseData);
+ getUserData(responseData);
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -168,6 +171,34 @@ public class LinkQQBot extends AppCompatActivity {
}
});
}
+ private void getUserData(String userId) throws Exception {
+ String url = "http://mai.godserver.cn:11451/api/qq/userData?qq=" + userId ;
+
+ Request request = new Request.Builder()
+ .url(url)
+ .build();
+ client.newCall(request).enqueue(new Callback() {
+
+ @Override
+ public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
+ if (response.isSuccessful()) {
+ String json = response.body().string();
+ UserData userData = new Gson().fromJson(json, UserData.class);
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putString("paikaname", userData.getUserName());
+ editor.putInt("iconId",userData.getIconId());
+ editor.putString("rating", userData.getPlayerRating() + "");
+ editor.apply();
+ Log.d("TAG", "onResponse: " + userData.getUserName());
+ }
+ }
+
+ @Override
+ public void onFailure(@NotNull Call call, @NotNull IOException e) {
+ Log.d("TAG", "onFailure: " + e.getMessage());
+ }
+ });
+ }
private void getUserRegionData(String userId) throws Exception {
String url = "http://mai.godserver.cn:11451/api/qq/region2?qq=" + userId ;
diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/MainActivity.java b/app/src/main/java/org/astral/findmaimaiultra/ui/MainActivity.java
index a60b11c..f74646d 100644
--- a/app/src/main/java/org/astral/findmaimaiultra/ui/MainActivity.java
+++ b/app/src/main/java/org/astral/findmaimaiultra/ui/MainActivity.java
@@ -2,12 +2,17 @@ package org.astral.findmaimaiultra.ui;
import android.Manifest;
import android.annotation.SuppressLint;
+import android.app.PendingIntent;
import android.content.*;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
import android.os.Bundle;
+import android.os.Parcelable;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -36,6 +41,11 @@ import org.astral.findmaimaiultra.ui.home.HomeFragment;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import static android.app.Activity.RESULT_OK;
@@ -44,15 +54,26 @@ public class MainActivity extends AppCompatActivity implements ImagePickerListen
private AppBarConfiguration mAppBarConfiguration;
private ActivityMainBinding binding;
private SharedPreferences settingProperties;
+ private NfcAdapter nfcAdapter;
+ private PendingIntent pendingIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ nfcAdapter = NfcAdapter.getDefaultAdapter(this);
+ if (nfcAdapter == null) {
+ Toast.makeText(this, "NFC is not available on this device", Toast.LENGTH_SHORT).show();
+ finish();
+ return;
+ }
+
+ pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_IMMUTABLE);
+ handleNfcIntent(getIntent());
+
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
settingProperties = getSharedPreferences("setting", Context.MODE_PRIVATE);
-
setSupportActionBar(binding.appBarMain.toolbar);
DrawerLayout drawer = binding.drawerLayout;
NavigationView navigationView = binding.navView;
@@ -67,6 +88,122 @@ public class MainActivity extends AppCompatActivity implements ImagePickerListen
NavigationUI.setupWithNavController(navigationView, navController);
}
+ @Override
+ protected void onResume() {
+ super.onResume();
+ if (nfcAdapter != null) {
+ nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ if (nfcAdapter != null) {
+ nfcAdapter.disableForegroundDispatch(this);
+ }
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ Log.d("111111111", "onNewIntent: " + intent.getAction());
+ handleNfcIntent(intent);
+ super.onNewIntent(intent);
+ }
+
+ private void handleNfcIntent(Intent intent) {
+ String action = intent.getAction();
+ if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action) || NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
+ Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
+ if (rawMsgs != null) {
+ NdefMessage[] msgs = new NdefMessage[rawMsgs.length];
+ for (int i = 0; i < rawMsgs.length; i++) {
+ msgs[i] = (NdefMessage) rawMsgs[i];
+ }
+ // Process the messages
+ List nfcData = processNdefMessages(msgs);
+ for (String data : nfcData) {
+ if(data.contains("paika")) {
+ Intent intent2 = new Intent(this, PaikaActivity.class);
+ intent2.putExtra("data", data);
+ startActivity(intent2);
+ }
+ // 在这里处理NFC数据
+ }
+ }
+ }
+ }
+
+ private List processNdefMessages(NdefMessage[] msgs) {
+ List nfcData = new ArrayList<>();
+ if (msgs == null || msgs.length == 0) return nfcData;
+
+ for (NdefMessage msg : msgs) {
+ NdefRecord[] records = msg.getRecords();
+ for (NdefRecord record : records) {
+ String recordData = parseNdefRecord(record);
+ if (recordData != null) {
+ nfcData.add(recordData);
+ }
+ }
+ }
+ return nfcData;
+ }
+
+ private String parseNdefRecord(NdefRecord record) {
+ if (record.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(record.getType(), NdefRecord.RTD_URI)) {
+ return parseUri(record);
+ } else if (record.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(record.getType(), NdefRecord.RTD_TEXT)) {
+ return parseText(record);
+ } else {
+ // 处理其他类型的记录
+ return new String(record.getPayload(), StandardCharsets.UTF_8);
+ }
+ }
+
+ private String parseUri(NdefRecord record) {
+ byte[] uriField = record.getPayload();
+ String prefix = ((char) (uriField[0] & 0x0F)) + "";
+ byte[] fullUri = new byte[uriField.length - 1];
+ System.arraycopy(uriField, 1, fullUri, 0, uriField.length - 1);
+ return prefix + new String(fullUri, StandardCharsets.UTF_8);
+ }
+
+ private String parseText(NdefRecord record) {
+ byte[] payload = record.getPayload();
+ if (payload.length < 2) {
+ Log.w("NfcBroadcastReceiver", "Invalid payload length for text record");
+ return null;
+ }
+
+ // 第一个字节的高4位表示字符编码(0表示UTF-8,1表示UTF-16)
+ String textEncoding = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16";
+ int languageCodeLength = payload[0] & 0077;
+
+ if (languageCodeLength > payload.length - 1) {
+ Log.w("NfcBroadcastReceiver", "Invalid language code length");
+ return null;
+ }
+
+ // 解析语言代码(通常不需要,除非你有特殊需求)
+ String languageCode = new String(payload, 1, languageCodeLength, StandardCharsets.US_ASCII);
+
+ // 解析文本数据
+ int textStartIndex = 1 + languageCodeLength;
+ int textLength = payload.length - textStartIndex;
+
+ if (textLength <= 0) {
+ Log.w("NfcBroadcastReceiver", "No text data found");
+ return null;
+ }
+
+ try {
+ return new String(payload, textStartIndex, textLength, Charset.forName(textEncoding));
+ } catch (Exception e) {
+ Log.w("NfcBroadcastReceiver", "Unsupported charset: " + textEncoding, e);
+ return null;
+ }
+ }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
@@ -93,6 +230,7 @@ public class MainActivity extends AppCompatActivity implements ImagePickerListen
});
return false;
}
+
private void updatePlace() {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
LinearLayout layout = new LinearLayout(this);
diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/NfcActivity.java b/app/src/main/java/org/astral/findmaimaiultra/ui/NfcActivity.java
new file mode 100644
index 0000000..2c1768d
--- /dev/null
+++ b/app/src/main/java/org/astral/findmaimaiultra/ui/NfcActivity.java
@@ -0,0 +1,61 @@
+package org.astral.findmaimaiultra.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.widget.TextView;
+import org.astral.findmaimaiultra.R;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+public class NfcActivity extends Activity {
+ private TextView textView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_nfc);
+ textView = findViewById(R.id.textView);
+
+ Intent intent = getIntent();
+ if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
+ Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
+ if (rawMsgs != null) {
+ NdefMessage[] msgs = new NdefMessage[rawMsgs.length];
+ for (int i = 0; i < rawMsgs.length; i++) {
+ msgs[i] = (NdefMessage) rawMsgs[i];
+ }
+ // Process the messages
+ processNdefMessages(msgs);
+ }
+ }
+ }
+
+ private void processNdefMessages(NdefMessage[] msgs) {
+ if (msgs == null || msgs.length == 0) return;
+
+ for (NdefMessage msg : msgs) {
+ NdefRecord[] records = msg.getRecords();
+ for (NdefRecord record : records) {
+ if (record.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(record.getType(), NdefRecord.RTD_URI)) {
+ String uri = parseUri(record);
+ textView.setText(uri);
+ }
+ }
+ }
+ }
+
+ private String parseUri(NdefRecord record) {
+ byte[] uriField = record.getPayload();
+ String prefix = ((char) (uriField[0] & 0x0F)) + "";
+ byte[] fullUri = new byte[uriField.length - 1];
+ System.arraycopy(uriField, 1, fullUri, 0, uriField.length - 1);
+ return prefix + new String(fullUri, StandardCharsets.UTF_8);
+ }
+}
+
\ No newline at end of file
diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/NfcBroadcastReceiver.java b/app/src/main/java/org/astral/findmaimaiultra/ui/NfcBroadcastReceiver.java
new file mode 100644
index 0000000..40efbad
--- /dev/null
+++ b/app/src/main/java/org/astral/findmaimaiultra/ui/NfcBroadcastReceiver.java
@@ -0,0 +1,102 @@
+package org.astral.findmaimaiultra.ui;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.os.Build;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+public class NfcBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
+ Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
+ if (rawMsgs != null) {
+ NdefMessage[] msgs = new NdefMessage[rawMsgs.length];
+ for (int i = 0; i < rawMsgs.length; i++) {
+ msgs[i] = (NdefMessage) rawMsgs[i];
+ }
+ // Process the messages
+ processNdefMessages(context, msgs);
+ }
+ }
+ }
+
+ private void processNdefMessages(Context context, NdefMessage[] msgs) {
+ if (msgs == null || msgs.length == 0) return;
+
+ for (NdefMessage msg : msgs) {
+ NdefRecord[] records = msg.getRecords();
+ for (NdefRecord record : records) {
+ if (record.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(record.getType(), NdefRecord.RTD_URI)) {
+ String uri = parseUri(record);
+ Log.d("NfcBroadcastReceiver", "URI: " + uri);
+ // 你可以在这里启动MainActivity或者执行其他操作
+ Intent mainIntent = new Intent(context, MainActivity.class);
+ mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(mainIntent);
+ } else if (record.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(record.getType(), NdefRecord.RTD_TEXT)) {
+ String text = parseText(record);
+ Log.d("NfcBroadcastReceiver", "Text: " + text);
+ // 你可以在这里启动MainActivity或者执行其他操作
+ Intent mainIntent = new Intent(context, MainActivity.class);
+ mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mainIntent.putExtra("nfc_text", text);
+ context.startActivity(mainIntent);
+ }
+ }
+ }
+ }
+
+ private String parseUri(NdefRecord record) {
+ byte[] uriField = record.getPayload();
+ String prefix = ((char) (uriField[0] & 0x0F)) + "";
+ byte[] fullUri = new byte[uriField.length - 1];
+ System.arraycopy(uriField, 1, fullUri, 0, uriField.length - 1);
+ return prefix + new String(fullUri, StandardCharsets.UTF_8);
+ }
+
+ private String parseText(NdefRecord record) {
+ byte[] payload = record.getPayload();
+ if (payload.length < 2) {
+ Log.w("NfcBroadcastReceiver", "Invalid payload length for text record");
+ return null;
+ }
+
+ // 第一个字节的高4位表示字符编码(0表示UTF-8,1表示UTF-16)
+ String textEncoding = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16";
+ int languageCodeLength = payload[0] & 0077;
+
+ if (languageCodeLength > payload.length - 1) {
+ Log.w("NfcBroadcastReceiver", "Invalid language code length");
+ return null;
+ }
+
+ // 解析语言代码(通常不需要,除非你有特殊需求)
+ String languageCode = new String(payload, 1, languageCodeLength, StandardCharsets.US_ASCII);
+
+ // 解析文本数据
+ int textStartIndex = 1 + languageCodeLength;
+ int textLength = payload.length - textStartIndex;
+
+ if (textLength <= 0) {
+ Log.w("NfcBroadcastReceiver", "No text data found");
+ return null;
+ }
+
+ try {
+ return new String(payload, textStartIndex, textLength, Charset.forName(textEncoding));
+ } catch (Exception e) {
+ Log.w("NfcBroadcastReceiver", "Unsupported charset: " + textEncoding, e);
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/PaikaActivity.java b/app/src/main/java/org/astral/findmaimaiultra/ui/PaikaActivity.java
index eab9f0b..49d7df6 100644
--- a/app/src/main/java/org/astral/findmaimaiultra/ui/PaikaActivity.java
+++ b/app/src/main/java/org/astral/findmaimaiultra/ui/PaikaActivity.java
@@ -2,429 +2,547 @@ package org.astral.findmaimaiultra.ui;
import android.annotation.SuppressLint;
import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
import android.content.SharedPreferences;
-import android.graphics.Typeface;
import android.os.Handler;
import android.util.Log;
+import android.view.LayoutInflater;
import android.view.View;
import android.widget.*;
-import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import com.bumptech.glide.Glide;
import com.google.android.material.button.MaterialButton;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import com.google.android.material.dialog.MaterialDialogs;
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputEditText;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import okhttp3.*;
import org.astral.findmaimaiultra.R;
+import org.jetbrains.annotations.NotNull;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
public class PaikaActivity extends AppCompatActivity {
- private MaterialButton enter;
- private TextInputEditText partyName;
- private Context context;
- private OkHttpClient client;
- private String party;
- private TextView partyHouse;
- private TableLayout tableLayout;
private SharedPreferences sharedPreferences;
- private TextInputEditText name;
- private String paikaname;
- private MaterialButton add;
- private MaterialButton play;
- private MaterialButton leave;
- private MaterialButton card;
- private Handler handler;
- private String cardStyle;
- private String old = "";
+ private String use_party;
+ private String use_name;
+ private int iconId;
+ private int iconResId = iconId;
+ private int status;
+ private Toolbar toolbar;
+ private List players = new ArrayList<>();
+ private Handler handler = new Handler();
+ private ImageView player1Avatar;
+ private ImageView player2Avatar;
+ private TextView player1Name;
+ private TextView player2Name;
+ private boolean isPlaying = false;
@SuppressLint("MissingInflatedId")
@Override
protected void onStart() {
super.onStart();
setContentView(R.layout.activity_paika);
- enter = findViewById(R.id.enter);
- partyName = findViewById(R.id.party);
- context = getApplicationContext();
- client = new OkHttpClient();
- add = findViewById(R.id.add);
- leave = findViewById(R.id.leave);
- play = findViewById(R.id.play);
- tableLayout = findViewById(R.id.tableLayout);
- sharedPreferences = getSharedPreferences("setting", MODE_PRIVATE);
- name = findViewById(R.id.name);
- partyHouse= findViewById(R.id.partyHouse);
- card = findViewById(R.id.card);
- handler = new Handler();
- if(sharedPreferences.getString("paikaname", null) != null) {
- name.setText(sharedPreferences.getString("paikaname", null));
- paikaname = sharedPreferences.getString("paikaname", null);
+ sharedPreferences = getSharedPreferences("setting", Context.MODE_PRIVATE);
+ handler.postDelayed(refreshTask, 3000);
+
+ use_name = sharedPreferences.getString("paikaname", "");
+ iconId = sharedPreferences.getInt("iconId", 0);
+ iconResId = iconId;
+ player1Avatar = findViewById(R.id.player1Avatar);
+ player2Avatar = findViewById(R.id.player2Avatar);
+ player1Name = findViewById(R.id.player1Name);
+ player2Name = findViewById(R.id.player2Name);
+ if (use_name.equals("")) {
+ //询问并做个名字
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
+ builder.setTitle("请输入昵称");
+ TextInputEditText textInputEditText = new TextInputEditText(this);
+ builder.setView(textInputEditText);
+ builder.setPositiveButton("确定", (dialog, which) -> {
+ use_name = textInputEditText.getText().toString();
+ dialog.dismiss();
+ });
+ builder.setNegativeButton("取消", null);
+ builder.show();
}
- enter.setOnClickListener(v -> {
- enterParty();
- });
- cardStyle = sharedPreferences.getString("cardStyle", "maimai PiNK.png");
- if (!cardStyle.contains(".")){
- cardStyle = cardStyle + ".png";
- }
- card.setText(cardStyle.split("\\.")[0]);
- add.setOnClickListener(v -> {
- paikaname = name.getText().toString();
- if(paikaname.equals("")) {
- Toast.makeText(context, "请输入昵称", Toast.LENGTH_SHORT).show();
- } else {
- updateCard();
- RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), "{\"party\":\"" + party + "\",\"name\":\"" + paikaname + "\"}");
- Request request = new Request.Builder()
- .url("http://mai.godserver.cn:11451/api/mai/v1/party?party=" + party + "&people=" + paikaname)
- .post(requestBody)
- .build();
+
+ status = sharedPreferences.getInt("paikastatus", 0);
+ toolbar = findViewById(R.id.toolbar);
+
+ Intent intent = getIntent();
+ if (intent.getStringExtra("data") != null) {
+ String data = intent.getStringExtra("data");
+ Log.d("123456", data);
+
+ use_party = data.split("paika")[1];
+ Log.d("partySetting", use_party);
+
+ if (sharedPreferences.getString("use_party", "").equals(use_party)) {
+ getData();
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (players != null && !players.isEmpty()) {
+ // 如果 players 不为空,执行 doUPlay()
+ doUPlay();
+ } else {
+ // 如果 players 为空,继续延迟 1 秒后检查
+ handler.postDelayed(this, 1000);
+ }
+ }
+ }, 1000); // 延迟 1 秒
+
+ }else {
+ toolbar.setTitle(use_party + " 房间 " + use_name);
+ }
+ }else
+ if(!sharedPreferences.getString("use_party", "").equals("")) {
+ use_party = sharedPreferences.getString("use_party", "");
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
+ builder.setTitle("重新进入房间");
+ builder.setMessage("重新进入房间号?");
+ TextInputEditText textInputEditText = new TextInputEditText(this);
+ builder.setView(textInputEditText);
+ textInputEditText.setText(use_party);
+ builder.setPositiveButton("确定", (dialog, which) -> {
+ use_party = textInputEditText.getText().toString();
+
+ if (status == 0) {
+ toolbar.setTitle(use_party + " 房间 " + use_name);
+ }else {
+ toolbar.setTitle(use_party + " 房间 " + use_name + " 正在队列");
+ }
SharedPreferences.Editor editor = sharedPreferences.edit();
- editor.putString("paikaname", paikaname);
+ editor.putString("use_party", use_party);
editor.apply();
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
- joinParty();
- }
-
- @Override
- public void onFailure(@NonNull Call call, @NonNull IOException e) {
-
- }
- });
- }
- });
- leave.setOnClickListener(v->{
- Request request = new Request.Builder()
- .url("http://mai.godserver.cn:11451/api/mai/v1/party?party=" + party + "&people=" + paikaname)
- .delete()
- .build();
- play.setVisibility(View.GONE);
-
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
- joinParty();
- }
-
- @Override
- public void onFailure(@NonNull Call call, @NonNull IOException e) {
-
- }
+ getData();
});
- });
- play.setOnClickListener(v->{
- RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), "{\"party\":\"" + party + "\",\"people\":\"" + paikaname + "\"}");
- Request request = new Request.Builder()
- .url("http://mai.godserver.cn:11451/api/mai/v1/partyPlay?party=" + party)
- .post(requestBody)
- .build();
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
- if (response.isSuccessful()) {
- joinParty();
- }
- }
- @Override
- public void onFailure(@NonNull Call call, @NonNull IOException e) {
- }
+ builder.setNegativeButton("取消", null);
+ builder.show();
+ }else if (status == 0 && intent.getStringExtra("data") == null) {
+ //询问加入房价
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
+ builder.setTitle("进入房间");
+ builder.setMessage("进入房间号?");
+ TextInputEditText textInputEditText = new TextInputEditText(this);
+ builder.setView(textInputEditText);
+ builder.setPositiveButton("确定", (dialog, which) -> {
+ use_party = textInputEditText.getText().toString();
+ toolbar.setTitle(use_party + " 房间 " + use_name);
+
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putString("use_party", use_party);
+ editor.apply();
+ getData();
});
- });
- card.setOnClickListener(v -> {
- Toast.makeText(context, "目前样式:" + cardStyle, Toast.LENGTH_SHORT).show();
-
- // 创建 AlertDialog
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("请选择卡牌样式");
-
- // 加载自定义布局
- View dialogView = getLayoutInflater().inflate(R.layout.dialog_card_style, null);
- LinearLayout layout = dialogView.findViewById(R.id.layout_buttons); // 假设 LinearLayout 的 id 是 layout_buttons
-
- // 添加选项
- String[] styles = {
- "maimai でらっくす FESTiVAL PLUS",
- "maimai でらっくす UNiVERSE PLUS",
- "maimai でらっくす PLUS",
- "maimai でらっくす FESTiVAL",
- "maimai でらっくす UNiVERSE",
- "maimai でらっくす BUDDiES",
- "maimai でらっくす",
- "maimai MURASAKi",
- "maimai PiNK",
- "maimai ORANGE",
- "maimai GreeN",
- "maimai MiLK"
- };
-
- // 创建 AlertDialog 对象
- AlertDialog dialog = builder.create();
-
- for (String style : styles) {
- MaterialButton button = new MaterialButton(this);
- button.setText(style);
- button.setPadding(16, 16, 16, 16);
- button.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
- button.setTextColor(getResources().getColor(R.color.white));
- button.setOnClickListener(view -> {
- cardStyle = style + ".png";
- updateCard();
- Toast.makeText(context, "已选择样式: " + cardStyle, Toast.LENGTH_SHORT).show();
- dialog.dismiss();
- });
- layout.addView(button);
- }
-
- // 设置 AlertDialog 的内容视图
- dialog.setView(dialogView);
-
- // 显示 AlertDialog
- dialog.show();
- });
-
- }
- private void updateCard() {
- RequestBody emptyRequestBody = RequestBody.create("", MediaType.parse("text/plain"));
- Request request = new Request.Builder()
- .url("http://mai.godserver.cn:11451/api/mai/v1/player?party=" + party + "&people=" + paikaname + "&card=" + cardStyle)
- .post(emptyRequestBody)
- .build();
- card.setText(cardStyle.split("\\.")[0]);
- SharedPreferences.Editor editor = sharedPreferences.edit();
- editor.putString("cardStyle", cardStyle);
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
- Log.d("TAG", "Response: " + response.body().string());
- }
-
- @Override
- public void onFailure(@NonNull Call call, @NonNull IOException e) {
-
- }
- });
- }
- private void enterParty() {
- LinearLayout joinParty = findViewById(R.id.joinParty);
- joinParty.setVisibility(LinearLayout.VISIBLE);
- LinearLayout enterParty = findViewById(R.id.enterParty);
- enterParty.setVisibility(LinearLayout.GONE);
- TextInputEditText partyName = findViewById(R.id.party);
- party = partyName.getText().toString();
- if (!name.getText().toString().isEmpty()) {
- paikaname = name.getText().toString();
+ builder.setNegativeButton("取消", null);
+ builder.show();
}
- handler = new Handler();
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- joinParty();
- handler.postDelayed(this, 5000);
- }
- };
- handler.post(runnable);
- }
- private void joinParty() {
- getShangJiPeople();
- Request request = new Request.Builder()
- .url("http://mai.godserver.cn:11451/api/mai/v1/party?party=" + party)
- .build();
- Log.d("MainLaunch", "onResponse: " + request);
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
- if (response.isSuccessful()) {
- String responseData = null;
- try {
- responseData = response.body().string();
- if(old.equals(responseData)) {
- return;
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- String finalResponseData = responseData;
- SharedPreferences.Editor editor = sharedPreferences.edit();
- editor.putString("paikaname", paikaname);
- editor.commit();
- runOnUiThread(() -> {
- List list = new Gson().fromJson(finalResponseData, new TypeToken>() {
- }.getType());
- tableLayout.removeAllViews();
-
- // 表头行
- TableRow headerRow = new TableRow(context);
- addTextViewToRow(headerRow, "排卡顺序", 2);
- addTextViewToRow(headerRow, "昵称", 5);
- addTextViewToRow(headerRow, "辅助操作此玩家", 4);
- tableLayout.addView(headerRow);
-
- // 数据行
- for (int i = 0; i < list.size(); i++) {
- String name = list.get(i);
- if (i == 0) {
- play.setVisibility(name.equals(paikaname) ? View.VISIBLE : View.GONE);
- }
- TableRow row = new TableRow(context);
-
- // 排卡顺序
- addTextViewToRow(row, (i + 1) + "", 1);
-
- // 昵称(图片 + 文字)
- LinearLayout nameLayout = new LinearLayout(context);
- nameLayout.setOrientation(LinearLayout.VERTICAL);
- TableRow.LayoutParams layoutParams = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 5);
- nameLayout.setLayoutParams(layoutParams);
-
- // 图片
- ImageView imageView = new ImageView(context);
- updateUserCard( imageView,name);
- nameLayout.addView(imageView);
-
- // 文字
- TextView textView = new TextView(context);
- textView.setText(name);
- textView.setTextSize(14);
- textView.setPadding(30, 20, 0, 0);
- //设置颜色colorPrimary
- //设计成斜式
- textView.setTypeface(Typeface.create("serif-italic", Typeface.NORMAL));
- textView.setTextColor(getResources().getColor(R.color.colorSecondary));
- nameLayout.addView(textView);
-
- row.addView(nameLayout);
-
- // 辅助操作按钮
- addButtonToRow(row, "插队", 1, name);
- addButtonToRow(row, "上机", 1, name);
- addButtonToRow(row, "离开", 1, name);
-
- tableLayout.addView(row);
- }
- });
- old = finalResponseData;
- }
- }
-
- @Override
- public void onFailure(@NonNull Call call, @NonNull IOException e) {
- Log.e("MainLaunch", "onFailure: ", e);
- }
- });
- }
- private void updateUserCard(ImageView imageView,String people) {
- Request request = new Request.Builder()
- .url("http://mai.godserver.cn:11451/api/mai/v1/player?people=" + people + "&party=" + party)
- .build();
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
- if(response.isSuccessful()) {
- String responseData = response.body().string();
- runOnUiThread(()->{
- Glide.with(context)
- .load("http://cdn.godserver.cn/resource/static/mai/pic/" + responseData) // 图片URL
- .placeholder(R.drawable.placeholder) // 占位图
- .into(imageView);
- });
- }
- }
-
- @Override
- public void onFailure(@NonNull Call call, @NonNull IOException e) {
- Toast.makeText(context, "卡牌展示失败", Toast.LENGTH_SHORT).show();
- }
- });
- }
- // 辅助方法:添加 TextView 到 TableRow 并设置权重
- private void addTextViewToRow(TableRow row, String text, int weight) {
- TextView textView = new TextView(context);
- textView.setText(text);
- textView.setTextColor(ContextCompat.getColor(context, R.color.textcolorPrimary));
- TableRow.LayoutParams params = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, weight);
- textView.setLayoutParams(params);
- row.addView(textView);
- }
-
- // 辅助方法:添加 Button 到 TableRow 并设置权重
- private void addButtonToRow(TableRow row, String text, int weight,String username) {
- Button button = new Button(context);
- button.setText(text);
- if(text.equals("插队")) {
- addButton(button,"change",paikaname,username);
- }else if(text.equals("上机")) {
- addButton(button,"play",paikaname,username);
- }else if(text.equals("离开")) {
- addButton(button,"leave",paikaname,username);
+ Log.d("123456", status + "");
+ toolbar.setTitle(use_party + " 房间 " + use_name);
+ if (status == 1) {
+ toolbar.setTitle(use_party + " 房间 " + use_name + " 正在队列");
}
- TableRow.LayoutParams params = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, weight);
- button.setLayoutParams(params);
- row.addView(button);
- }
- private void addButton(Button button,String data1,String data0,String data) {
- button.setOnClickListener(new View.OnClickListener() {
+ toolbar.setTitleTextColor(ContextCompat.getColor(this, R.color.white));
+ // 添加测试数据到 TableLayout
+ FloatingActionButton fab = findViewById(R.id.fab);
+ fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- Request request = null;
- if(data1.equals("change")) {
- RequestBody body = RequestBody.create(data1, MediaType.get("application/json; charset=utf-8"));
- request = new Request.Builder()
- .url("http://mai.godserver.cn:11451/api/mai/v1/party?party=" + party + "&people=" + data0 + "&changeToPeople=" + data)
- .put(body)
- .build();
- }else if(data1.equals("play")) {
- RequestBody body = RequestBody.create(data1, MediaType.get("application/json; charset=utf-8"));
- request = new Request.Builder()
- .url("http://mai.godserver.cn:11451/api/mai/v1/partyPlay?party=" + party + "&people=" + data)
- .delete(body)
- .build();
- }else if(data1.equals("leave")) {
- RequestBody body = RequestBody.create(data1, MediaType.get("application/json; charset=utf-8"));
- request = new Request.Builder()
- .url("http://mai.godserver.cn:11451/api/mai/v1/party?party=" + party + "&people=" + data)
- .delete(body)
- .build();
- }
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
- Log.d("TAG", "onResponse: " + response.body().string());
- runOnUiThread(()->{
- Toast.makeText(PaikaActivity.this, "操作成功", Toast.LENGTH_SHORT);
- });
- joinParty();
- }
-
- @Override
- public void onFailure(@NonNull Call call, @NonNull IOException e) {
-
- }
- });
+ doFab(view);
}
});
}
- public void getShangJiPeople() {
+
+ private void doUPlay() {
+ // 使用 MaterialAlertDialogBuilder 创建弹窗
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
+ LayoutInflater inflater = getLayoutInflater();
+ View dialogView = inflater.inflate(R.layout.dialog_uplay, null);
+ dialogView.setMinimumWidth(600);
+ dialogView.setMinimumHeight(1000);
+ builder.setView(dialogView);
+
+ // 获取按钮并设置点击事件
+ MaterialButton btnPlay = dialogView.findViewById(R.id.btnPlay);
+ AtomicInteger num = new AtomicInteger();
+
+ for (int i = 0; i < players.size();i ++) {
+ if(players.get(i).equals(use_name + "()" + iconId)) {
+ Log.d("UPlayDialog", "num:" + i);
+ num.set(i);
+ break;
+ }
+ }
+ // 创建并显示弹窗
+ AlertDialog dialog = builder.create();
+ btnPlay.setOnClickListener(v -> {
+ // 处理“上机”按钮点击事件
+ num.set(-1);
+
+ for (int i = 0; i < players.size();i ++) {
+ if(players.get(i).equals(use_name + "()" + iconId)) {
+ Log.d("UPlayDialog", "num:" + i);
+ num.set(i);
+ Log.d("UPlayDialog", use_name + "()" + iconId);
+ Log.d("UPlayDialog", players.get(i));
+ break;
+ }
+ }
+ if (num.get() == 2 || num.get() == 3) {
+ Log.d("UPlayDialog", "上机 clicked");
+ play();
+ } else if (num.get() == 1 || num.get() ==0) {
+ Snackbar.make(v, "正在上机!", Snackbar.LENGTH_SHORT)
+ .setAction("确定", null)
+ .show();
+ } else if (players.isEmpty()) {
+ Snackbar.make(v, "还在加载队列", Snackbar.LENGTH_SHORT)
+ .setAction("确定", null)
+ .show(); } else {
+ Snackbar.make(v, "还在排队!如特殊情况请点击顺位头像请求换位", Snackbar.LENGTH_SHORT)
+ .setAction("确定", null)
+ .show();
+ }
+ dialog.dismiss();
+ // 可以在这里添加更多的逻辑
+ });
+
+ if (num.get() ==0 | num.get() == 1) {
+ Snackbar.make(findViewById(R.id.back), "正在上机!", Snackbar.LENGTH_SHORT)
+ .setAction("确定", null)
+ .show();
+ }else {
+ dialog.show();
+ }
+
+ // 设置弹窗为全屏大小
+ if (dialog.getWindow() != null) {
+ dialog.getWindow().setLayout(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.MATCH_PARENT
+ );
+ }
+ }
+
+
+
+
+ private void doFab(View view) {
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
+ View dialogView = LayoutInflater.from(this).inflate(R.layout.paika_dialog, null);
+
+ MaterialButton addButton = dialogView.findViewById(R.id.addButton);
+ addButton.setOnClickListener(v -> {
+ status = 1;
+ toolbar.setTitle(use_party + " 房间 " + use_name + " 正在队列");
+
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putInt("paikastatus", status);
+ editor.putString("use_party", use_party);
+ editor.commit();
+
+ join();
+ });
+ MaterialButton leaveButton = dialogView.findViewById(R.id.leaveButton);
+ leaveButton.setOnClickListener(v -> {
+ status = 0;
+ toolbar.setTitle(use_party + " 房间 " + use_name);
+
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putInt("paikastatus", status);
+ editor.commit();
+
+ remove();
+ });
+ MaterialButton leaveRoomButton = dialogView.findViewById(R.id.leaveRoomButton);
+ leaveRoomButton.setOnClickListener(v -> {
+ status = 0;
+
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putInt("paikastatus", status);
+ editor.putString("use_party", "");
+ editor.commit();
+
+ remove();
+ Intent intent = new Intent(PaikaActivity.this, MainActivity.class);
+ startActivity(intent);
+ });
+ builder.setView(dialogView);
+ builder.show();
+
+ }
+ private Runnable refreshTask = new Runnable() {
+ @Override
+ public void run() {
+ if (!use_party.isEmpty()) {
+ getData(); // 调用刷新方法
+ }
+ handler.postDelayed(this, 3000); // 每隔 2 秒执行一次
+ }
+ };
+ private void getData() {
Request request = new Request.Builder()
- .url("http://mai.godserver.cn:11451/api/mai/v1/partyPlay?party=" + party)
+ .url("http://mai.godserver.cn:11451/api/mai/v1/party?party=" + use_party)
.build();
+ OkHttpClient client = new OkHttpClient();
client.newCall(request).enqueue(new Callback() {
@Override
- public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
- String data = response.body().string();
- runOnUiThread(()->{
- partyHouse.setText("房间号"+ party+" "+data + "正在上机");
- });
+ public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
+ if (response.isSuccessful()) {
+ String res = response.body().string();
+ players = new Gson().fromJson(res, new TypeToken>() {
+ }.getType());
+ addDataToTableLayout();
+ }
}
@Override
- public void onFailure(@NonNull Call call, @NonNull IOException e) {
+ public void onFailure(@NotNull Call call, @NotNull IOException e) {
+
+ }
+ });
+ Log.d("123456", "getData");
+ }
+ private void join() {
+ Request request = new Request.Builder()
+ .url("http://mai.godserver.cn:11451/api/mai/v1/party?party=" + use_party + "&people=" + use_name + "()" + iconId)
+ .post(RequestBody.create("", MediaType.parse("application/json")))
+ .build();
+ OkHttpClient client = new OkHttpClient();
+ client.newCall(request).enqueue(new Callback() {
+ @Override
+ public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
+ if (response.isSuccessful()) {
+ Snackbar.make(findViewById(R.id.back), "加入成功", Snackbar.LENGTH_LONG)
+ .setAction("Action", null).show();
+ getData();
+ }
+ }
+ @Override
+ public void onFailure(@NotNull Call call, @NotNull IOException e) {
+
+ }
+ });
+ Log.d("123456", "getData"); }
+ private void remove() {
+ Log.d("123456", "remove");
+ Request request = new Request.Builder()
+ .url("http://mai.godserver.cn:11451/api/mai/v1/party?party=" + use_party + "&people=" + use_name + "()" + iconId)
+ .delete(RequestBody.create("", MediaType.parse("application/json")))
+ .build();
+ OkHttpClient client = new OkHttpClient();
+ client.newCall(request).enqueue(new Callback() {
+ @Override
+ public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
+ if (response.isSuccessful()) {
+ Snackbar.make(findViewById(R.id.back), "退出成功", Snackbar.LENGTH_LONG)
+ .setAction("Action", null).show();
+ getData();
+ }
+ }
+
+ @Override
+ public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
});
}
+ private void play() {
+ Request request = new Request.Builder()
+ .url("http://mai.godserver.cn:11451/api/mai/v1/partyPlay?party=" + use_party )
+ .post(RequestBody.create("", MediaType.parse("application/json")))
+ .build();
+ OkHttpClient client = new OkHttpClient();
+ client.newCall(request).enqueue(new Callback() {
+ @Override
+ public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
+ Snackbar.make(findViewById(R.id.back), "上机成功!", Snackbar.LENGTH_LONG)
+ .setAction("Action", null).show();
+ getData();
+ }
+
+ @Override
+ public void onFailure(@NotNull Call call, @NotNull IOException e) {
+
+ }
+ });
+ }
+ private void unplay() {
+ }
+ private void addDataToTableLayout() {
+ Context context = this;
+
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ TableLayout tableLayout = findViewById(R.id.tableLayout);
+ //清空
+ tableLayout.removeAllViews();
+ try {
+ Glide.with(context)
+ .load("https://assets2.lxns.net/maimai/icon/" + Integer.parseInt(players.get(0).split("\\(\\)")[1]) +".png")
+ .into(player1Avatar);
+ Glide.with(context)
+ .load("https://assets2.lxns.net/maimai/icon/" + Integer.parseInt(players.get(1).split("\\(\\)")[1]) +".png")
+ .into(player2Avatar);
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ player1Name.setText(players.get(0).split("\\(\\)")[0]);
+ player2Name.setText(players.get(1).split("\\(\\)")[0]);
+
+ for (int i = 2; i < players.size(); i++) {
+ String name = players.get(i).split("\\(\\)")[0];
+ int iconId = Integer.parseInt(players.get(i).split("\\(\\)")[1]);
+ TableRow tableRow = (TableRow) LayoutInflater.from(context).inflate(R.layout.table_row_item, tableLayout, false);
+ int finalI = i;
+ ImageView userAvatar = tableRow.findViewById(R.id.userAvatar);
+ try {
+ Glide.with(context)
+ .load("https://assets2.lxns.net/maimai/icon/" + iconId +".png")
+ .into(userAvatar);
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ TextView username = tableRow.findViewById(R.id.username);
+ username.setText(name);
+ tableLayout.addView(tableRow);
+
+ tableRow.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context);
+ builder.setTitle("操作");
+ View view = LayoutInflater.from(context).inflate(R.layout.paika_item_dialog, null);
+ builder.setView(view);
+ MaterialButton change = view.findViewById(R.id.change);
+ change.setText("插队");
+ MaterialButton removeButton = view.findViewById(R.id.removeButton);
+ removeButton.setText("移除");
+ MaterialButton fuzhushangji = view.findViewById(R.id.fuzhushangji);
+ fuzhushangji.setText("辅助上机");
+
+ change.setOnClickListener(v2->{
+ Request request = new Request.Builder()
+ .url("http://mai.godserver.cn:11451/api/mai/v1/party?party=" + use_party + "&people=" + use_name + "()" + iconResId + "&changeToPeople=" + players.get(finalI))
+ .put(RequestBody.create("", MediaType.parse("application/json")))
+ .build();
+ OkHttpClient client = new OkHttpClient();
+ Log.d("123456", "http://mai.godserver.cn:11451/api/mai/v1/party?party=" + use_party + "&people=" + use_name + "()" + iconResId + "&changeToPeople=" + players.get(finalI));
+ client.newCall(request).enqueue(new Callback() {
+ @Override
+ public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
+ if (response.isSuccessful()) {
+ getData();
+ Log.d("123456", "onResponse: " + response.body().string());
+ Snackbar.make(findViewById(R.id.back), "换位成功", Snackbar.LENGTH_LONG)
+ .setAction("Action", null).show();
+ }
+ }
+
+ @Override
+ public void onFailure(@NotNull Call call, @NotNull IOException e) {
+
+ }
+ });
+ });
+ removeButton.setOnClickListener(v2->{
+ Request request = new Request.Builder()
+ .url("http://mai.godserver.cn:11451/api/mai/v1/party?party=" + use_party + "&people=" +players.get(finalI))
+ .delete(RequestBody.create("", MediaType.parse("application/json")))
+ .build();
+ OkHttpClient client = new OkHttpClient();
+ client.newCall(request).enqueue(new Callback() {
+ @Override
+ public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
+ if (response.isSuccessful()) {
+ getData();
+ Snackbar.make(findViewById(R.id.back), "移除成功", Snackbar.LENGTH_LONG)
+ .setAction("Action", null).show();
+ }
+ }
+
+ @Override
+ public void onFailure(@NotNull Call call, @NotNull IOException e) {
+
+ }
+ });
+ });
+ fuzhushangji.setOnClickListener(v2->{
+ if (finalI == 2 ) {
+ Request request = new Request.Builder()
+ .url("http://mai.godserver.cn:11451/api/mai/v1/partyPlay?party=" + use_party )
+ .post(RequestBody.create("", MediaType.parse("application/json")))
+ .build();
+ OkHttpClient client = new OkHttpClient();
+ client.newCall(request).enqueue(new Callback() {
+ @Override
+ public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
+ if (response.isSuccessful()) {
+ getData();
+ Snackbar.make(findViewById(R.id.back), "辅助上机成功", Snackbar.LENGTH_LONG)
+ .setAction("Action", null).show();
+ }
+ }
+
+ @Override
+ public void onFailure(@NotNull Call call, @NotNull IOException e) {
+ Log.d("123456", "onFailure: " + e);
+ }
+ });
+ }else {
+ Snackbar.make(findViewById(R.id.back), "辅助上机失败,位置不满足要求", Snackbar.LENGTH_LONG)
+ .setAction("Action", null).show();
+ }
+
+ });
+
+ builder.show();
+ }
+ });
+ // 添加分割线
+ if (finalI < players.size() - 1) {
+ View separator = new View(context);
+ separator.setLayoutParams(new TableLayout.LayoutParams(
+ TableLayout.LayoutParams.MATCH_PARENT,
+ 1
+ ));
+ separator.setBackgroundColor(ContextCompat.getColor(context, R.color.dividerColor));
+ tableLayout.addView(separator);
+ }
+ }
+ }
+ });
+ }
+ // 用户类
+ private static class User {
+ private String name;
+ private int avatar;
+
+ public User(String name, int avatar) {
+ this.name = name;
+ this.avatar = avatar;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getAvatar() {
+ return avatar;
+ }
+ }
}
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
index 1590530..3d2773e 100644
--- a/app/src/main/java/org/astral/findmaimaiultra/ui/home/HomeFragment.java
+++ b/app/src/main/java/org/astral/findmaimaiultra/ui/home/HomeFragment.java
@@ -98,6 +98,7 @@ public class HomeFragment extends Fragment {
}
sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
+
}
@Override
diff --git a/app/src/main/java/org/astral/findmaimaiultra/ui/pixiv/PixivFragment.java b/app/src/main/java/org/astral/findmaimaiultra/ui/pixiv/PixivFragment.java
index 78addf1..532705d 100644
--- a/app/src/main/java/org/astral/findmaimaiultra/ui/pixiv/PixivFragment.java
+++ b/app/src/main/java/org/astral/findmaimaiultra/ui/pixiv/PixivFragment.java
@@ -218,19 +218,25 @@ public class PixivFragment extends Fragment {
.build();
if (query.matches("\\d+")) {
request = new Request.Builder()
- .url("jm.godserver.cn:35621/album/" + query + "/")
+ .url("http://jm.godserver.cn:35621/album/" + query + "/")
.build();
type = 1;
}
- snackbar = Snackbar.make(requireView(), "加载中", Snackbar.LENGTH_SHORT);
+ snackbar = Snackbar.make(requireView(), "加载中", Snackbar.LENGTH_INDEFINITE);
+ //snackbar长时间显示
+
snackbar.show();
int finalType = type;
Snackbar finalSnackbar = snackbar;
+ Log.d("TAG", "fetchDataJM: " + type);
+ Log.d("TAG", "fetchDataJM: " + query);
+ Log.d("URL", "fetchDataJM: " + request.url());
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String json = response.body().string();
if (response.isSuccessful()) {
+ finalSnackbar.dismiss();
if(finalType == 0) {
System.out.println(json);
Gson gson = new Gson();
@@ -255,7 +261,13 @@ public class PixivFragment extends Fragment {
// 隐藏 Snackbar
finalSnackbar.dismiss();
});
- }else if (finalType == 1) {
+ }else {
+ handler.post(() -> {
+ path2.setVisibility(View.GONE);
+ recyclerView.setVisibility(View.GONE);
+ path2.setVisibility(View.VISIBLE);
+ });
+ Log.d("fetchDataJM", "onResponse: " + json);
Album albumItem = new Gson().fromJson(json, Album.class);
openJMProject(albumItem);
}
@@ -264,13 +276,25 @@ public class PixivFragment extends Fragment {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
-
+ handler.post(() -> {
+ // 处理失败情况
+ Toast.makeText(requireContext(), "超时", Toast.LENGTH_SHORT).show();
+ finalSnackbar.dismiss();
+ });
}
});
}
private void fetchData(String word, int page, Snackbar snackbar) {
+ if (word.matches("\\d+")) {
+ IllustData illustData = new IllustData();
+ illustData.setId(word);
+ illustData.setTitle(word);
+ illustData.setUrl(word);
+ openIllustData(illustData);
+ return;
+ }
OkHttpClient client = new OkHttpClient();
//设置超时时间60s
client.newBuilder().connectTimeout(60, TimeUnit.SECONDS);
@@ -427,6 +451,8 @@ public class PixivFragment extends Fragment {
user.setText(photoResponse.getBody().getUserName());
TextView des = view.findViewById(R.id.des);
des.setText(photoResponse.getBody().getDescription());
+ builder.setTitle(photoResponse.getBody().getIllustTitle());
+
});
}
}
diff --git a/app/src/main/res/layout/activity_nfc.xml b/app/src/main/res/layout/activity_nfc.xml
new file mode 100644
index 0000000..b42f30f
--- /dev/null
+++ b/app/src/main/res/layout/activity_nfc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_paika.xml b/app/src/main/res/layout/activity_paika.xml
index f4b6aaa..1ca0e6b 100644
--- a/app/src/main/res/layout/activity_paika.xml
+++ b/app/src/main/res/layout/activity_paika.xml
@@ -1,125 +1,140 @@
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" xmlns:tools="http://schemas.android.com/tools"
+ android:background="@color/colorOnPrimary"
+ android:fillViewport="true"
+ android:orientation="vertical">
-
-
-
+ android:layout_height="?attr/actionBarSize"
+ android:background="@color/colorPrimary"
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
+ app:titleTextColor="@color/white"
+ app:subtitleTextColor="@color/white"
+ android:tooltipText="@string/app_name"
+ app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+ app:cardCornerRadius="16dp"
+ app:cardElevation="4dp">
-
-
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:padding="16dp">
-
+
+
+
+
+
+
+
-
+ android:layout_margin="8dp"
+ android:layout_weight="1"
+ app:cardCornerRadius="16dp"
+ app:cardElevation="4dp">
+
-
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
+
+
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/dialog_uplay.xml b/app/src/main/res/layout/dialog_uplay.xml
new file mode 100644
index 0000000..ed9c775
--- /dev/null
+++ b/app/src/main/res/layout/dialog_uplay.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/jm_dialog.xml b/app/src/main/res/layout/jm_dialog.xml
index 70dfdcd..bdc77d3 100644
--- a/app/src/main/res/layout/jm_dialog.xml
+++ b/app/src/main/res/layout/jm_dialog.xml
@@ -44,6 +44,10 @@
+
diff --git a/app/src/main/res/layout/paika_dialog.xml b/app/src/main/res/layout/paika_dialog.xml
new file mode 100644
index 0000000..69b74de
--- /dev/null
+++ b/app/src/main/res/layout/paika_dialog.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/paika_item_dialog.xml b/app/src/main/res/layout/paika_item_dialog.xml
new file mode 100644
index 0000000..69330aa
--- /dev/null
+++ b/app/src/main/res/layout/paika_item_dialog.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/table_row_item.xml b/app/src/main/res/layout/table_row_item.xml
new file mode 100644
index 0000000..d233118
--- /dev/null
+++ b/app/src/main/res/layout/table_row_item.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 0124fec..a341925 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -29,4 +29,7 @@
#000000
#F44336
+ #FF9189
+
+ #7D7D7D
\ No newline at end of file
diff --git a/app/src/main/res/xml/nfc_filter.xml b/app/src/main/res/xml/nfc_filter.xml
new file mode 100644
index 0000000..9f8a9dd
--- /dev/null
+++ b/app/src/main/res/xml/nfc_filter.xml
@@ -0,0 +1,5 @@
+
+
+ android.nfc.tech.Ndef
+
+