RecyclerView新增Item时自动触发数据上传的实现方案问询
Automatically Upload Audio When New Item is Added to RecyclerView
Got it, let's adjust your RecyclerView Adapter so that when a new item is added, it automatically triggers the audio upload via postingData() method. Here's the modified code with key changes explained:
Key Changes Made:
- Added a
Set<String> uploadedFilesto track already uploaded audio files, preventing duplicate uploads - Created an
addNewSong()method to safely add new items to the adapter and trigger auto-upload - Extracted network connectivity check into a reusable
isNetworkConnected()method (updated to use modern API for Android 10+ compatibility) - Triggered upload logic right after notifying the adapter about the new item
- Added proper null checks and error handling to avoid crashes
- Added upload status UI updates (success/failure indicators)
class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> { public ArrayList<String> songNames; Context context; Handler seekHandler = new Handler(); Runnable run; // Track uploaded files to avoid duplicate upload attempts private Set<String> uploadedFiles = new HashSet<>(); // Reference to RecyclerView to access view holders for new items private RecyclerView recyclerView; public RecyclerViewAdapter(ArrayList<String> songNames, Context context) { this.songNames = songNames; this.context = context; // Uncomment below if you don't want to upload existing items on adapter initialization // uploadedFiles.addAll(songNames); } // Attach RecyclerView reference when setting adapter @Override public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); this.recyclerView = recyclerView; } // Method to add new song and trigger auto-upload public void addNewSong(String songPath) { songNames.add(songPath); int newItemPosition = songNames.size() - 1; notifyItemInserted(newItemPosition); // Trigger auto-upload for the new item if (isNetworkConnected()) { Toast.makeText(context, "Starting audio upload...", Toast.LENGTH_SHORT).show(); // Get view holder for the new position (if it's already bound to UI) MyViewHolder holder = (MyViewHolder) recyclerView.findViewHolderForAdapterPosition(newItemPosition); postingData(newItemPosition, holder); } else { Toast.makeText(context, "No internet connection - upload will retry later", Toast.LENGTH_SHORT).show(); // Optional: Add to a pending upload queue to retry when network is restored } } @NonNull @Override public RecyclerViewAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View listItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.record_card, parent, false); return new MyViewHolder(listItem); } @Override public void onBindViewHolder(@NonNull final RecyclerViewAdapter.MyViewHolder holder, final int position) { final String currentSongPath = songNames.get(position); holder.textView.setText(currentSongPath); // Keep manual upload option if needed holder.textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { holder.playerCard.setVisibility(View.VISIBLE); if (isNetworkConnected()) { Toast.makeText(context, "Internet is active", Toast.LENGTH_SHORT).show(); postingData(position, holder); } else { Toast.makeText(context, "No internet connection", Toast.LENGTH_SHORT).show(); } } }); // Existing media player controls (unchanged) holder.cardView1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { holder.playerCard.setVisibility(View.VISIBLE); } }); final MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); try { mediaPlayer.setDataSource(currentSongPath); mediaPlayer.prepare(); } catch (IOException e) { e.printStackTrace(); } holder.seekBar.setMax(mediaPlayer.getDuration()); holder.seekBar.setTag(position); holder.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (mediaPlayer != null && fromUser) { mediaPlayer.seekTo(progress); } } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }); holder.seekBarHint.setText("0:00/" + calculateDuration(mediaPlayer.getDuration())); holder.playsong.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!mediaPlayer.isPlaying()) { mediaPlayer.start(); holder.pauseRec.setVisibility(View.VISIBLE); holder.playsong.setVisibility(View.INVISIBLE); holder.playsong.setText(" Pause "); run = new Runnable() { @Override public void run() { holder.seekBar.setProgress(mediaPlayer.getCurrentPosition()); seekHandler.postDelayed(run, 100); int miliSeconds = mediaPlayer.getCurrentPosition(); if (miliSeconds != 0) { long minutes = TimeUnit.MILLISECONDS.toMinutes(miliSeconds); long seconds = TimeUnit.MILLISECONDS.toSeconds(miliSeconds); if (minutes == 0) { holder.seekBarHint.setText("0:" + seconds + "/" + calculateDuration(mediaPlayer.getDuration())); } else { if (seconds >= 60) { long sec = seconds - (minutes * 60); holder.seekBarHint.setText(minutes + ":" + sec + "/" + calculateDuration(mediaPlayer.getDuration())); } } } else { int totalTime = mediaPlayer.getDuration(); long minutes = TimeUnit.MILLISECONDS.toMinutes(totalTime); long seconds = TimeUnit.MILLISECONDS.toSeconds(totalTime); if (minutes == 0) { holder.seekBarHint.setText("0:" + seconds); } else { if (seconds >= 60) { long sec = seconds - (minutes * 60); holder.seekBarHint.setText(minutes + ":" + sec); } } } } }; run.run(); } else { mediaPlayer.pause(); holder.pauseRec.setVisibility(View.INVISIBLE); holder.playsong.setVisibility(View.VISIBLE); holder.playsong.setText(" Play "); } } }); holder.pauseRec.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mediaPlayer.pause(); holder.playsong.setVisibility(View.VISIBLE); holder.pauseRec.setVisibility(View.GONE); } }); // Show upload status if already uploaded if (uploadedFiles.contains(currentSongPath)) { holder.recdonpost.setVisibility(View.VISIBLE); holder.notdone.setVisibility(View.GONE); } else { holder.recdonpost.setVisibility(View.GONE); holder.notdone.setVisibility(View.VISIBLE); } } private void postingData(final int position, final MyViewHolder holder) { final String songPath = songNames.get(position); // Skip upload if already completed if (uploadedFiles.contains(songPath)) { Toast.makeText(context, "Audio already uploaded", Toast.LENGTH_SHORT).show(); return; } SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); final String userId = preferences.getString("user_id", "0"); String currentTime = preferences.getString("currentDate", "1"); SharedPreferences sp = context.getSharedPreferences("MyPrefs", Context.MODE_PRIVATE); String prospectNumber = sp.getString("prospectNumber", "1234567891"); System.out.println("prospectNumber: " + prospectNumber); OkHttpClient client = new OkHttpClient(); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", songPath, RequestBody.create(MediaType.parse("application/octet-stream"), new File(songPath))) .addFormDataPart("user_id", userId) .addFormDataPart("file_name", "Call Recording") .addFormDataPart("creation_datetime", currentTime) .addFormDataPart("prospect_number", prospectNumber) .addFormDataPart("call_type","incoming") .build(); Request request = new Request.Builder() .url("http://159.65.145.32/api/file/upload/") .post(requestBody) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); uploadedFiles.remove(songPath); // Update UI on main thread ((Activity)context).runOnUiThread(() -> { Toast.makeText(context, "Upload failed - please try again", Toast.LENGTH_SHORT).show(); if (holder != null) { holder.notdone.setVisibility(View.VISIBLE); holder.recdonpost.setVisibility(View.GONE); } }); } @Override public void onResponse(Call call, final Response response) throws IOException { if (!response.isSuccessful()) { throw new IOException("Unexpected code " + response); } else { String jsonResponse = response.body().string(); System.out.println("Upload Response >>> " + jsonResponse); uploadedFiles.add(songPath); // Update UI on main thread ((Activity)context).runOnUiThread(() -> { Toast.makeText(context, "Upload successful!", Toast.LENGTH_SHORT).show(); if (holder != null) { holder.recdonpost.setVisibility(View.VISIBLE); holder.notdone.setVisibility(View.GONE); } }); } } }); } // Modern network connectivity check (works on Android 10+) private boolean isNetworkConnected() { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (cm != null) { NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork()); return capabilities != null && ( capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ); } return false; } @Override public int getItemCount() { return songNames.size(); } public static class MyViewHolder extends RecyclerView.ViewHolder { TextView textView, seekBarHint; TextView playsong, pauseRec; public static SeekBar seekBar; CardView playerCard, cardView1; ImageView recdonpost, notdone; public MyViewHolder(@NonNull View itemView) { super(itemView); textView = itemView.findViewById(R.id.card_item); playsong = itemView.findViewById(R.id.recplay); seekBarHint = itemView.findViewById(R.id.songDur); seekBar = itemView.findViewById(R.id.seekbar); playerCard = itemView.findViewById(R.id.playerCard); cardView1 = itemView.findViewById(R.id.layout1); pauseRec = itemView.findViewById(R.id.recPause); recdonpost = itemView.findViewById(R.id.recdonpost); // Ensure this ID exists in your layout notdone = itemView.findViewById(R.id.notdone); // Ensure this ID exists in your layout } } private String calculateDuration(int duration) { String finalDuration = ""; long minutes = TimeUnit.MILLISECONDS.toMinutes(duration); long seconds = TimeUnit.MILLISECONDS.toSeconds(duration); if (minutes == 0) { finalDuration = "0:" + seconds; } else { if (seconds >= 60) { long sec = seconds - (minutes * 60); finalDuration = minutes + ":" + sec; } } return finalDuration; } }
How to Use the Modified Adapter:
When adding a new audio file to the RecyclerView, call the addNewSong() method instead of directly modifying the songNames list:
// Example in your Activity/Fragment recyclerViewAdapter.addNewSong("/storage/emulated/0/MyRecordings/new_call.mp3");
Additional Notes:
- Pending Uploads: For offline scenarios, implement a pending upload queue using
WorkManageror aBroadcastReceiverto retry when the network is restored. - Permissions: Ensure your app has
INTERNET,READ_EXTERNAL_STORAGE(Android <13), orREAD_MEDIA_AUDIO(Android 13+) permissions. - Memory Leaks: Consider releasing
MediaPlayerinstances inonViewRecycled()to avoid memory leaks. - Upload Status UI: Make sure
recdonpostandnotdoneImageViews exist in yourrecord_cardlayout to show upload success/failure.
内容的提问来源于stack exchange,提问作者Rahul K
相关产品推荐
相关产品推荐

