When I do listView.setAdapter(adapter) in second activity, the app crashes. Whereas if I do the same thing in the first Activity the app works fine. All the id are allocated properly to there variables.
There is one third activity where it plays the music , after clicking on the name of the music in the list view of second activity.
Now the question is why i created a second activity to display the listview, whereas i could have done it in the first activity, so here is the reason.
In the first activity , the app reads the data from the storage and makes a arraylist out of that, this takes time(like it takes 5secs to load the song and there is no display in that while), so if i am in the playing song activity and I want to go back to first activity, it will again take time to read the data from the storage, so as a result I created one more activty for just displaying the song in the list, so reading data is done only once in first activity which sends the data to the second activity in form of array. So when i press back from third activity(parent activity set as second activity ), I'll directly get the list,as the array will be already initialised in the second activity by the first activity at the starting of the app.
I haven't added a intent from second to third activity yet since the second activity is not working. But the third activity works fine because before I had only 2 activities, the first activity where it loaded the songs and also displayed the list and second activity for playing songs where it played the songs properly. Now from since I seperated the first activity into 2, I'm getting this error for listview adapter
First Activity
The listView in here, I created just for testing case,to check if the string array is proper, but the main listview in second Activity where i want to display the list, doesnt works, the app crashes, even though everything is same , obviously except for the Resourse IDs. But it doesnt crashes in this activity.
package com.example.imusic;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.Manifest;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
ListView listView;
//RecyclerView recyclerView;
ArrayList<File> Song;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Dexter.withContext(this)
.withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
.withListener(new PermissionListener(){
@Override
public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) {
// Toast.makeText(MainActivity.this, "Persmission Granted", Toast.LENGTH_SHORT).show();
Song=fetchSongs(Environment.getExternalStorageDirectory()); //gets external storage directory and passes it to the function which then return list of al songs
// Song=fetchSongs(Environment.getExternalStorageDirectory()); //gets external storage directory and passes it to the function which then return list of al songs
String []items=new String[Song.size()];//create string arr of size Song
for(int i=0;i<Song.size();i++){
items[i]=Song.get(i).getName().replace(".mp3","");// put the names of song in array and replaces .mp3 with " "
}
Intent intent=new Intent(MainActivity.this,MainActivity3.class);
intent.putExtra("songlist",Song);
intent.putExtra("stringlist",items);
listView=findViewById(R.id.listView);
// CustomAdapter adapter=new CustomAdapter(MainActivity.this,R.layout.mylayout,items);
// listView.setAdapter(adapter);
startActivity(intent);
// Toast.makeText(MainActivity.this, "Successfully created", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionDenied(PermissionDeniedResponse permissionDeniedResponse) {
// Toast.makeText(MainActivity.this, "Persmission Denied", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) {
permissionToken.continuePermissionRequest();
}
})
.check();
}
public ArrayList<File> fetchSongs(File file){
ArrayList<File> arrayList=new ArrayList<>();//File array
File []files =file.listFiles(); //list all the files in files variable from external storage directory
if(files!=null){//should work only if it is not null
for(File f: files){//its like for i in files
if(!f.isHidden() && f.isDirectory()){// if the file is not hidden and present in the directory then only proceeds
arrayList.addAll(fetchSongs(f)); //recursive function that return the list of songs
}
else{
if(f.getName().endsWith(".mp3") && !f.getName().startsWith(".")){// check it its a mp3 file
arrayList.add(f);//adds mp3 file to array
}
}
}
}
return arrayList; //return the list
}
}
Second Activity
The main listview is in here, where i display the songs. IDs are also properly allocated
package com.example.imusic;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import android.Manifest;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
public class MainActivity3 extends AppCompatActivity {
ListView listView;
ArrayList<File> Song;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView=findViewById(R.id.listView24);
Intent intent=getIntent();
Bundle b=intent.getExtras();
Toast.makeText(this, "MainActivity3", Toast.LENGTH_SHORT).show();
Song=(ArrayList) b.getParcelableArrayList("songlist"); // Song=fetchSongs(Environment.getExternalStorageDirectory()); //gets external storage directory and passes it to the function which then return list of al songs
String []items=new String[Song.size()];//create string arr of size Song
for(int i=0;i<Song.size();i++){
items[i]=Song.get(i).getName().replace(".mp3","");// put the names of song in array and replaces .mp3 with " "
}
String[] itemss=intent.getStringArrayExtra("stringlist");
int j=0;
while(j<items.length){
Log.d("String",items[j]);
j++;
}
CustomAdapter adapter=new CustomAdapter(this,R.layout.mylayout,itemss);
listView.setAdapter(adapter);
}
}
This is my CustomAdapter Class
Here I took the input as String array and then overrided the 2 methods getItem() and getView()
The ID of the textView in custom resource file is textView2
package com.example.imusic;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
public class CustomAdapter extends ArrayAdapter {
String [] arr;
public CustomAdapter(@NonNull Context context, int resource, @NonNull String[] objects) {
super(context, resource, objects);
int j=0;
this.arr=objects;
while(j<arr.length){
Log.d("items",arr[j]);
j++;
}
}
@Nullable
@Override
public String getItem(int position) {
return arr[position];
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
convertView=LayoutInflater.from(getContext()).inflate(R.layout.mylayout,parent,false);
TextView t=convertView.findViewById(R.id.textView2);
t.setText(getItem(position));
Log.d("items","hello");
return convertView;
}
}
