V1.0.0(3),优化

This commit is contained in:
lihongwei 2024-09-12 13:59:43 +08:00
parent c660170265
commit 4831c39881
14 changed files with 207 additions and 79 deletions

View File

@ -28,15 +28,6 @@ public class NewRecordActivity extends AppCompatActivity {
private long startTime;
private MediaRecorder mediaRecorder;
private File outputFile;
private Runnable updateTimeTask = new Runnable() {
@Override
public void run() {
long currentTime = System.currentTimeMillis();
long elapsedTime = currentTime - startTime;
binding.newRecordTime.setText(formatTime(elapsedTime));
handler.postDelayed(this, 1000);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -55,7 +46,7 @@ public class NewRecordActivity extends AppCompatActivity {
}
});
binding.newRecordBack.setOnClickListener(v -> finish());
binding.newRecordBack.setOnClickListener(v -> onBackPressed());
}
private void toggleRecording() {
@ -69,6 +60,17 @@ public class NewRecordActivity extends AppCompatActivity {
isStarted = !isStarted; // 切换录音状态
}
//每个一秒更新显示录音时长
private Runnable updateTimeTask = new Runnable() {
@Override
public void run() {
long currentTime = System.currentTimeMillis();
long elapsedTime = currentTime - startTime;
binding.newRecordTime.setText(formatTime(elapsedTime));
handler.postDelayed(this, 1000);
}
};
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
@ -137,9 +139,40 @@ public class NewRecordActivity extends AppCompatActivity {
return String.format("%02d:%02d:%02d", hours, minutes, seconds);
}
@Override
public void onBackPressed() {
if (isStarted) {
// 停止录音并释放MediaRecorder
if (mediaRecorder != null) {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
}
// 删除录音文件
deleteRecordingFile();
}
finish();
super.onBackPressed();
}
private void deleteRecordingFile() {
if (outputFile != null && outputFile.exists()) {
boolean deleted = outputFile.delete();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(updateTimeTask);
if (isStarted) {
// 停止录音并释放MediaRecorder
if (mediaRecorder != null) {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
}
deleteRecordingFile();
}
}
}

View File

@ -1,5 +1,6 @@
package com.sound.prankparty.Activity;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
@ -11,6 +12,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.activity.OnBackPressedCallback;
import androidx.appcompat.app.AppCompatActivity;
import com.sound.prankparty.R;
@ -19,6 +21,7 @@ import com.sound.prankparty.Room.SaveSounds;
import com.sound.prankparty.Room.SaveSoundsDao;
import com.sound.prankparty.databinding.ActivitySaveRecordBinding;
import java.io.File;
import java.io.IOException;
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
@ -67,7 +70,16 @@ public class SaveRecordActivity extends AppCompatActivity {
// 设置焦点变化监听器
binding.saveRecordName.setOnFocusChangeListener((v, hasFocus) -> binding.saveRecordName.setCursorVisible(hasFocus));
binding.saveRecordBack.setOnClickListener(v -> finish());
binding.saveRecordBack.setOnClickListener(v -> handleBackPressed());
// 添加 OnBackPressedCallback 来处理返回操作
getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
// 调用相同的处理逻辑
handleBackPressed();
}
});
// 处理全局点击事件
binding.main.setOnClickListener(v -> {
@ -87,7 +99,8 @@ public class SaveRecordActivity extends AppCompatActivity {
binding.saveRecordSave.setOnClickListener(v -> {
inputText = binding.saveRecordName.getText().toString();
if (inputText == null || inputText.trim().isEmpty()) {
//检测是否输入为空字符串
if (inputText.trim().isEmpty()) {
Toast.makeText(getApplicationContext(), "名称不能为空", Toast.LENGTH_SHORT).show();
return;
}
@ -107,6 +120,19 @@ public class SaveRecordActivity extends AppCompatActivity {
});
}
public void handleBackPressed() {
// 删除录音文件
deleteRecordingFile();
finish();
}
private void deleteRecordingFile() {
File file = new File(audioFilePath);
if (file.exists()) {
boolean deleted = file.delete();
}
}
private void clearFocusFromAllChildren(ViewGroup parent) {
for (int i = 0; i < parent.getChildCount(); i++) {
View child = parent.getChildAt(i);
@ -180,8 +206,10 @@ public class SaveRecordActivity extends AppCompatActivity {
mediaPlayer.release();
mediaPlayer = null;
}
deleteRecordingFile();
}
@SuppressLint("DefaultLocale")
private String formatTime(int duration) {
int seconds = (duration / 1000) % 60;
int minutes = (duration / (1000 * 60)) % 60;

View File

@ -15,8 +15,6 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.sound.MainApplication;
import com.sound.prankparty.Activity.PlaySoundActivity;
import com.sound.prankparty.JSON.SoundItem;
@ -26,9 +24,9 @@ import java.util.List;
public class AirHornRecyclerViewAdapter extends RecyclerView.Adapter<AirHornRecyclerViewAdapter.AirhonrViewHolder> {
private Context context;
private List<SoundItem> soundItemList;
private int color;
private final Context context;
private final List<SoundItem> soundItemList;
private final int color;
public AirHornRecyclerViewAdapter(Context context, List<SoundItem> soundItemList,int color) {
this.context = context;
@ -64,8 +62,6 @@ public class AirHornRecyclerViewAdapter extends RecyclerView.Adapter<AirHornRecy
holder.textView.setText("");
}
if (soundItem != null) {
Glide.with(MainApplication.getContext())
//指定加载的资源类型为Drawable
.asDrawable()
@ -82,7 +78,6 @@ public class AirHornRecyclerViewAdapter extends RecyclerView.Adapter<AirHornRecy
intent.putExtra("1234", soundItem);
context.startActivity(intent);
});
}
}
@ -91,7 +86,7 @@ public class AirHornRecyclerViewAdapter extends RecyclerView.Adapter<AirHornRecy
return soundItemList.size();
}
static class AirhonrViewHolder extends RecyclerView.ViewHolder {
public static class AirhonrViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;

View File

@ -48,13 +48,6 @@ public class FavoriteRecyclerViewAdapter extends RecyclerView.Adapter<FavoriteRe
};
}
public void updateData(List<FavoriteSounds> newFavoriteSoundsList) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new FavoriteSoundsDiffCallback(favoriteSoundsList, newFavoriteSoundsList));
favoriteSoundsList.clear();
favoriteSoundsList.addAll(newFavoriteSoundsList);
diffResult.dispatchUpdatesTo(this);
}
@NonNull
@Override
public FavoriteRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@ -92,12 +85,19 @@ public class FavoriteRecyclerViewAdapter extends RecyclerView.Adapter<FavoriteRe
.into(holder.imageView);
}
public void updateData(List<FavoriteSounds> newFavoriteSoundsList) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new FavoriteSoundsDiffCallback(favoriteSoundsList, newFavoriteSoundsList));
favoriteSoundsList.clear();
favoriteSoundsList.addAll(newFavoriteSoundsList);
diffResult.dispatchUpdatesTo(this);
}
@Override
public int getItemCount() {
return favoriteSoundsList != null ? favoriteSoundsList.size() : 0;
}
static class FavoriteRecyclerViewHolder extends RecyclerView.ViewHolder {
public static class FavoriteRecyclerViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;

View File

@ -112,7 +112,7 @@ public class RadioRecyclerViewAdapter extends RecyclerView.Adapter<RadioRecycler
holder.favorite.setImageResource(isFavorite ? R.drawable.favorite : R.drawable.unfavorite);
}
static class RadioViewHolder extends RecyclerView.ViewHolder {
public static class RadioViewHolder extends RecyclerView.ViewHolder {
private TextView title;
private TextView date;

View File

@ -16,10 +16,8 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.sound.prankparty.Activity.AirHornActivity;
import com.sound.MainApplication;
import com.sound.prankparty.Activity.AirHornActivity;
import com.sound.prankparty.JSON.Category;
import com.sound.prankparty.R;

View File

@ -33,7 +33,7 @@ public class SoundRecyclerViewAdapter extends RecyclerView.Adapter<SoundRecycler
this.categoryList = categoryList;
colors = new int[]{
ContextCompat.getColor(context, R.color.color1),
ContextCompat.getColor(context, R.color.color4),
ContextCompat.getColor(context, R.color.color2),
ContextCompat.getColor(context, R.color.color3)
// 添加更多颜色

View File

@ -5,8 +5,10 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.GridLayoutManager;
import com.sound.prankparty.R;
@ -26,7 +28,7 @@ public class FavoriteFragment extends Fragment {
private FragmentFavoriteBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentFavoriteBinding.inflate(inflater, container, false);
View view = binding.getRoot();
@ -39,6 +41,9 @@ public class FavoriteFragment extends Fragment {
favoriteRecyclerViewAdapter = new FavoriteRecyclerViewAdapter(requireContext(), this);
binding.favoriteRecyclerview.setAdapter(favoriteRecyclerViewAdapter);
binding.favoriteRecyclerview.setItemAnimator(null); // 关闭默认动画
// RecyclerView 添加自定义的间距装饰
ItemDecoration itemDecoration = new ItemDecoration(16, 19, 10);
binding.favoriteRecyclerview.addItemDecoration(itemDecoration);
@ -57,6 +62,7 @@ public class FavoriteFragment extends Fragment {
binding.fragmentFavoriteTips.setVisibility(View.GONE);
binding.fragmentFavoriteImage.setVisibility(View.GONE);
}
favoriteRecyclerViewAdapter.updateData(favoriteSoundsList);
});
@ -66,8 +72,6 @@ public class FavoriteFragment extends Fragment {
@Override
public void onResume() {
super.onResume();
// 触发数据刷新
viewModel.refreshData();
}
@Override

View File

@ -12,6 +12,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -31,6 +32,7 @@ import com.sound.prankparty.Activity.NewRecordActivity;
import com.sound.prankparty.Adapter.RadioRecyclerViewAdapter;
import com.sound.prankparty.R;
import com.sound.prankparty.Room.AppDatabase;
import com.sound.prankparty.Room.FavoriteSounds;
import com.sound.prankparty.Room.FavoriteSoundsDao;
import com.sound.prankparty.Room.SaveSounds;
import com.sound.prankparty.Room.SaveSoundsDao;
@ -91,24 +93,12 @@ public class RadioFragment extends Fragment {
return view;
}
@Override
public void onResume() {
super.onResume();
refreshData();
}
public void deleteItem(int position) {
new Thread(() -> {
SaveSounds sound = saveSoundsList.get(position);
saveSoundsDao.deleteSound(sound);
requireActivity().runOnUiThread(() -> {
refreshData();
});
}).start();
}
private void showCustomBottomSheetDialog() {
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(requireContext());
View dialogView = LayoutInflater.from(requireContext()).inflate(R.layout.bottom_sheet_dialog, null);
@ -148,8 +138,8 @@ public class RadioFragment extends Fragment {
bottomSheetDialog.show();
}
// 处理权限请求结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
@ -161,8 +151,8 @@ public class RadioFragment extends Fragment {
}
}
}
// 打开音频选择器
private void openAudioPicker() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); // 改为 ACTION_OPEN_DOCUMENT
intent.setType("audio/*"); // 设置 MIME 类型为音频
@ -170,8 +160,8 @@ public class RadioFragment extends Fragment {
startActivityForResult(intent, REQUEST_CODE_PICK_AUDIO);
}
// 处理 Activity 结果
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
@ -192,9 +182,19 @@ public class RadioFragment extends Fragment {
String[] lastModifiedDateTime = getDateTimeFromLastModified(lastModifiedTime);
long finalDuration = duration;
new Thread(() -> {
try {
// 在插入数据库前检查该 URI 是否已经存在
int count = saveSoundsDao.countSoundsByUri(audioUri.toString());
if (count > 0) {
// 在主线程中显示文件已经存在的提示
requireActivity().runOnUiThread(() ->
Toast.makeText(requireContext(), "该文件已经导入过,不能重复导入", Toast.LENGTH_LONG).show());
} else {
// 插入新记录
saveSoundsDao.insertSound(new SaveSounds(fileName, audioUri.toString(), lastModifiedDateTime[0], lastModifiedDateTime[1], formatDuration(finalDuration)));
}
} catch (Exception e) {
e.printStackTrace();
// 在主线程中显示错误信息
@ -207,6 +207,7 @@ public class RadioFragment extends Fragment {
}
// 获取文件名
private String getFileName(Uri uri) {
String result = null;
if (Objects.equals(uri.getScheme(), "content")) {
@ -229,8 +230,8 @@ public class RadioFragment extends Fragment {
}
return result;
}
// 获取音频时长
private long getAudioDuration(Uri uri) throws IOException {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
@ -244,15 +245,15 @@ public class RadioFragment extends Fragment {
retriever.release();
}
}
// 格式化时长
private String formatDuration(long duration) {
long minutes = (duration / 1000) / 60;
long seconds = (duration / 1000) % 60;
return String.format(Locale.getDefault(), "%d:%02d", minutes, seconds);
}
//获取最后修改时间
public long getLastModifiedTime(Context context, Uri uri) {
long lastModifiedTime = 0;
@ -290,6 +291,42 @@ public class RadioFragment extends Fragment {
return new String[]{date, time};
}
public void deleteItem(int position) {
new Thread(() -> {
// 获取要删除的音频对象
SaveSounds sound = saveSoundsList.get(position);
String filePath = sound.getPath();
// 删除数据库中的收藏记录
FavoriteSounds favoriteSound = favoriteSoundsDao.getByPath(filePath);
if (favoriteSound != null) {
favoriteSoundsDao.delete(favoriteSound);
}
// 删除数据库中的音频记录
saveSoundsDao.deleteSound(sound);
// 删除文件系统中的实际录音文件
File file = new File(filePath);
if (file.exists()) {
boolean deleted = file.delete();
if (deleted) {
// 如果文件成功删除可以在这里执行其他操作比如记录日志
Log.d("DeleteItem", "录音文件已删除: " + filePath);
} else {
// 如果文件删除失败可以在这里处理
Log.e("DeleteItem", "删除录音文件失败: " + filePath);
}
} else {
// 如果文件不存在可以在这里处理
Log.w("DeleteItem", "录音文件不存在: " + filePath);
}
// 在主线程中刷新UI
requireActivity().runOnUiThread(this::refreshData);
}).start();
}
// 刷新数据
public void refreshData() {
new Thread(() -> {

View File

@ -64,6 +64,7 @@ public class SoundFragment extends Fragment {
View dialogView = LayoutInflater.from(requireContext()).inflate(R.layout.setting_dialog, null);
// 禁止点击其他页面取消
bottomSheetDialog.setCanceledOnTouchOutside(false);
TextView version = dialogView.findViewById(R.id.version_number);
//更新版本号

View File

@ -0,0 +1,33 @@
package com.sound;
import android.app.Application;
import android.content.Context;
public class MainApplication extends Application {
/**
* 全局的上下文
*/
private static Context mContext;
@Override
public void onCreate() {
super.onCreate();
//获取应用的上下文并赋值给 mContext
mContext = getApplicationContext();
}
/**
* 获取context
* @return
*/
public static Context getContext(){
return mContext;
}
//重写 onLowMemory 方法在系统内存不足时调用这里只是调用了父类的 onLowMemory 方法没有做其他处理
@Override
public void onLowMemory() {
super.onLowMemory();
}
}

View File

@ -12,6 +12,9 @@ public interface SaveSoundsDao {
@Insert
void insertSound(SaveSounds sound);
@Query("SELECT COUNT(*) FROM save_sounds WHERE path = :uri")
int countSoundsByUri(String uri);
@Query("SELECT * FROM save_sounds")
List<SaveSounds> getAllSounds();

View File

@ -83,7 +83,7 @@ public class RadioFragment extends Fragment {
recyclerView.setAdapter(radioRecyclerViewAdapter);
// 初始化 MyItemTouchHelperCallback
myItemTouchHelperCallback = new MyItemTouchHelperCallback();
myItemTouchHelperCallback = new MyItemTouchHelperCallback(this);
itemTouchHelper = new ItemTouchHelper(myItemTouchHelperCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);

View File

@ -25,10 +25,6 @@ public class FavoriteSoundsViewModel extends AndroidViewModel {
public LiveData<List<FavoriteSounds>> getFavoriteSoundsLiveData() {
return favoriteSoundsLiveData;
}
public void refreshData() {
// 这里不需要做任何事情因为 LiveData 会自动更新
}
}