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 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 + +