Android App - Java: Adding to an arrayList then updating a ListView

Search This thread

jason3460

New member
Apr 9, 2014
1
0
I have coded this android app which produces a listView containing songs which are streamed from the internet, and the user can play them by clicking them using the mediaPlayer.

What i am having trouble with is allowing the user to add a song to the arrayList that populates the ListView within MainActivity.java. I have used the settings page to add textboxes so the user can add their songs by inputting, Song Name, Artist and the Direct Link to the song. Though the code i have used for this doesn't work, it should add the Song Name, Artist and Direct Link into the array_list_music ArrayList, then update the ListView, or at least i think that is how it should be done, although after entering details and clicking the 'Add Song' button, and returning to the main page, the ListView does not that the newly added song.

I have shown my code below.

So if someone could help with this problem, that would be great, thanks.

MainActivity.java
Code:
package com.groupassignment.musicplayer;

import java.util.ArrayList;

import android.app.ListActivity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.MediaController;
import android.widget.Toast;

public class MainActivity extends ListActivity implements OnPreparedListener, MediaController.MediaPlayerControl {

	private static final String TAG = "AudioPlayer";
	private ListView list;
	public MainArrayAdapter adapter;
	private MediaPlayer mediaPlayer;
	private MediaController mediaController;
	private String audioFile;
	private Handler handler = new Handler();
	
	ArrayList<String> array_list_music = new ArrayList<String>();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		list = getListView();

		mediaPlayer = new MediaPlayer();
		mediaPlayer.setOnPreparedListener(this);
		mediaController = new MediaController(this);
		
		//ArrayList<String> array_list_music = new ArrayList<String>();

		//Used to add a song to the array list
		array_list_music
			.add("Jar of Hearts"
				+ " ### "
				+ "Christina Perri"
				+ " ### "
				+ "LINK");
		
		array_list_music
			.add("Save The World"
				+ " ### "
				+ "Swedish House Mafia feat. John Martin"
				+ " ### "
				+ "LINK");
		
		array_list_music
			.add("Bromance"
				+ " ### "
				+ "Avicii"
				+ " ### "
				+ "LINK");

		adapter = new MainArrayAdapter(MainActivity.this, array_list_music);
		setListAdapter(adapter);

		//used to display toast and to play song using the URL, when clicking on a song
		list.setOnItemClickListener(new OnItemClickListener() {

			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
				Object item = getListView().getItemAtPosition(arg2);
				String the_list_item = item.toString();

				Toast.makeText(MainActivity.this, "You are now listening to: " + the_list_item, Toast.LENGTH_LONG).show();

				String[] aux = the_list_item.split(" ### ");
				String url_to_play = aux[2];
				
				playAudio(url_to_play);//sends url from arraylist item to the playAudio method
			}
		});

	}
	
	//used to play audio using the android mediaPlayer
	private void playAudio(String url_to_play) {

		//stop & reset player
		try {
			mediaPlayer.stop();
			mediaPlayer.reset();
		} catch (Exception e) {
		}
		
		//set the url, prepare it, and then play it
		try {
			mediaPlayer.setDataSource(url_to_play);
			mediaPlayer.prepare();
			mediaPlayer.start();
		} catch (Exception e) {
			Log.e(TAG, "Could not open file " + url_to_play + ".", e);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {

		case R.id.action_settings:

			Intent i_settings = new Intent(MainActivity.this, SettingsActivity.class);
			startActivity(i_settings);

			break;

		}
		return true;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		mediaController.show();
		return false;
	}

	//used to hide media controller, stop the media player and to release the url.
	@Override
	protected void onStop() {
		super.onStop();
		mediaController.hide();
		mediaPlayer.stop();
		mediaPlayer.release();
	}

	@Override
	public boolean canPause() {
		return true;
	}

	@Override
	public boolean canSeekBackward() {

		return true;
	}

	@Override
	public boolean canSeekForward() {
		return true;
	}

	@Override
	public int getBufferPercentage() {
		return 0;
	}

	@Override
	public int getCurrentPosition() {
		 return mediaPlayer.getCurrentPosition();
	}

	@Override
	public int getDuration() {
		return mediaPlayer.getDuration();
	}

	@Override
	public boolean isPlaying() {
		return mediaPlayer.isPlaying();
	}

	@Override
	public void pause() {
		 mediaPlayer.pause();
	}

	@Override
	public void seekTo(int arg0) {
		 mediaPlayer.seekTo(arg0);
	}

	@Override
	public void start() {
		 mediaPlayer.start();
	}
	
	 public void onPrepared(MediaPlayer mediaPlayer) {
		    Log.d(TAG, "onPrepared");
		    mediaController.setMediaPlayer(this);
		    mediaController.setAnchorView(list);

		    handler.post(new Runnable() {
		      public void run() {
		        mediaController.setEnabled(true);
		        mediaController.show();
		        
		      }
		    });
		  }

	 //------- what can you do from here -------
	 // implement your own media player with buttons since this one is not behaving "smart"..
	 // make next,previous buttons
	 // highlight the list item on click
	 // add your own server for playing music
	 // anything you want :)
	 
}

MainArrayAdapter.java
Code:
package com.groupassignment.musicplayer;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import android.content.Context;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;

import com.groupassignment.musicplayer.R;

public class MainArrayAdapter extends ArrayAdapter<String> implements ListAdapter {

	private final Context context;
	private ArrayList<String> data_array;
	private List<DataSetObserver> observers = new LinkedList<DataSetObserver>();
	
	public MainArrayAdapter(Context context, ArrayList<String> list_of_ids) {

		super(context, R.layout.main_list_rowlayout, list_of_ids);
		this.context = context;
		this.data_array = list_of_ids;

	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {

		LayoutInflater inflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View rowView = inflater.inflate(R.layout.main_list_rowlayout, parent,
				false);

		TextView textView_main_row_song_name = (TextView) rowView
				.findViewById(R.id.textView_main_row_song_name);
		TextView textView_main_row_singer_name = (TextView) rowView
				.findViewById(R.id.textView_main_row_singer_name);

		try {

			String[] aux = data_array.get(position).split(" ### ");

			String song_name = aux[0];
			String artist = aux[1];
			String url = aux[2];

			textView_main_row_song_name.setText(song_name);
			textView_main_row_singer_name.setText(artist);

		} catch (Exception e) {
			// TODO: handle exception
		}

		return rowView;
	}
	
	public void setArray(ArrayList<String> data_array){
		this.data_array = data_array;
		for (DataSetObserver observer : observers){
			observer.onChanged();
		}
	}
	
	 @Override
	    public void registerDataSetObserver(DataSetObserver dataSetObserver) {
	        ((LinkedList) observers).addFirst(dataSetObserver);
	    }

	    @Override
	    public void unregisterDataSetObserver(DataSetObserver dataSetObserver) {
	        observers.remove(dataSetObserver);
	    }

}

SettingsActivity.java
Code:
package com.groupassignment.musicplayer;

import android.app.Activity;
import android.view.View;
import android.widget.EditText;

import com.groupassignment.musicplayer.R;

public class SettingsActivity extends Activity {
	
	public String str ="";
	String songName;
	String artist;
	String directLink;
	
	protected void onCreate(android.os.Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_settings);
		
		songName = ((EditText)findViewById(R.id.editTextSongName)).toString();
		artist = ((EditText)findViewById(R.id.editTextArtist)).toString();
		directLink = ((EditText)findViewById(R.id.editTextDirectLink)).toString();
		
	};
	
    public void buttonAddSongClicked(View v)
    {
       addSong(songName, artist, directLink);
    }
	
	 private void addSong(String artist, String songName, String directLink) 
	    {
		 MainActivity main = new MainActivity();
		 
	    	main.array_list_music
				.add( songName
					+ " ### "
					+ artist
					+ " ### "
					+ directLink);

	    	main.adapter.notifyDataSetChanged();
	    	main.adapter = new MainArrayAdapter(main, main.array_list_music);
	    }

}
 

Attachments

  • SuperMusic.rar
    1.9 MB · Views: 83

GRYMALA

Member
May 5, 2014
19
5
The problem is that you create new instances of adapter each time, instead of updating the existing one. Easy way to solve your problem is to change attributes of array_list_music and adapter to public static in your MainActivity and modify addSong inside SettingsActivity to:

Code:
private void addSong(String artist, String songName, String directLink) 
	    { 
	    	MainActivity.array_list_music
				.add( songName
					+ " ### "
					+ artist
					+ " ### "
					+ directLink);

	    	MainActivity.adapter.notifyDataSetChanged();
	    	
	    }