Search code examples
androidarraylistandroid-serviceandroid-sharedpreferencesgson

getting error wile using gson saving data and mediaplayer service


I am following this tutorial for a audio player .I am able to play song in service .But when I try to save the song using gson and send the arraylist to the service but when i click on the list item the app crash with error

FATAL EXCEPTION: main
              Process: com.example.neelay.level95, PID: 15133
              java.lang.RuntimeException: Unable to start service com.example.neelay.level95.MediaPlayerService@79fde5a with Intent { cmp=com.example.neelay.level95/.MediaPlayerService }: java.lang.RuntimeException: Failed to invoke private android.net.Uri() with no args
                  at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3034)
                  at android.app.ActivityThread.access$2200(ActivityThread.java:153)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:148)
                  at android.app.ActivityThread.main(ActivityThread.java:5441)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
               Caused by: java.lang.RuntimeException: Failed to invoke private android.net.Uri() with no args
                  at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:111)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:210)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
                  at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41)
                  at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82)
                  at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
                  at com.google.gson.Gson.fromJson(Gson.java:887)
                  at com.google.gson.Gson.fromJson(Gson.java:852)
                  at com.google.gson.Gson.fromJson(Gson.java:801)
                  at com.example.neelay.level95.StorageUtil.loadAudio(StorageUtil.java:42)
                  at com.example.neelay.level95.MediaPlayerService.onStartCommand(MediaPlayerService.java:106)
                  at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3017)
                  at android.app.ActivityThread.access$2200(ActivityThread.java:153) 
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449) 
                  at android.os.Handler.dispatchMessage(Handler.java:102) 
                  at android.os.Looper.loop(Looper.java:148) 
                  at android.app.ActivityThread.main(ActivityThread.java:5441) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628) 
               Caused by: java.lang.InstantiationException: Can't instantiate abstract class android.net.Uri
                  at java.lang.reflect.Constructor.newInstance(Native Method)
                  at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:108)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:210) 
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129) 
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220) 
                  at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41) 
                  at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82) 
                  at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61) 
                  at com.google.gson.Gson.fromJson(Gson.java:887) 
                  at com.google.gson.Gson.fromJson(Gson.java:852) 
                  at com.google.gson.Gson.fromJson(Gson.java:801) 
                  at com.example.neelay.level95.StorageUtil.loadAudio(StorageUtil.java:42) 
                  at com.example.neelay.level95.MediaPlayerService.onStartCommand(MediaPlayerService.java:106) 
                  at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3017) 
                  at android.app.ActivityThread.access$2200(ActivityThread.java:153) 
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449) 
                  at android.os.Handler.dispatchMessage(Handler.java:102) 
                  at android.os.Looper.loop(Looper.java:148) 
                  at android.app.ActivityThread.main(ActivityThread.java:5441) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628) 

error in service where i am getting error

 @Override
public int onStartCommand(Intent intent, int flags, int startId) {
    try {

        //Load data from SharedPreferences
        StorageUtil storage = new StorageUtil(getApplicationContext());
        audioList = storage.loadAudio();
        audioIndex = storage.loadAudioIndex();

        if (audioIndex != -1 && audioIndex < audioList.size()) {
            //index is in a valid range
            activeAudio = audioList.get(audioIndex);
        } else {
            stopSelf();
        }
    } catch (NullPointerException e) {
        stopSelf();
    }

    //Request audio focus
    if (requestAudioFocus() == false) {
        //Could not gain focus
        stopSelf();
    }

    if (mediaSessionManager == null) {
        try {
            initMediaSession();
            initMediaPlayer();
        } catch (RemoteException e) {
            e.printStackTrace();
            stopSelf();
        }
        buildNotification(PlaybackStatus.PLAYING);
    }

    //Handle Intent action from MediaSession.TransportControls
    handleIncomingActions(intent);
    return super.onStartCommand(intent, flags, startId);
}

error in songutil class where it is showing error

 public ArrayList<Songfileinfo> loadAudio() {
    preferences = context.getSharedPreferences(STORAGE, Context.MODE_PRIVATE);
    Gson gson = new Gson();
    String json = preferences.getString("audioArrayList", null);
    Type type = new TypeToken<ArrayList<Songfileinfo>>() {
    }.getType();
    return gson.fromJson(json, type);
}

I am only able to know that i am getting error in service class at line 106 audioList = storage.loadAudio();and in songutil class at line 41 return gson.fromJson(json, type);but how I can fix this any help will be helpfull.Now I am able to play the song when i remove some code from songfileinfo here is the code

public class Songfileinfo implements Serializable {
private String title,album,artist,file_uri;

// private Uri album_art; // private long duration;

public Songfileinfo(String data, String title, String album, String artist) {
    this.file_uri = data;
    this.title = title;
    this.album = album;
    this.artist = artist;
}

public Songfileinfo() {

}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getAlbum() {
    return album;
}

public void setAlbum(String album) {
    this.album = album;
}

public String getArtist() {
    return artist;
}

public void setArtist(String artist) {
    this.artist = artist;
}

public String getFile_uri() {
    return file_uri;
}

public void setFile_uri(String file_uri) {
    this.file_uri = file_uri;
}

}

but when i add thes lises of code it is still getting crashed

private Uri album_art;
private long duration;
 public Uri getAlbum_art() {
    return album_art;
}

public void setAlbum_art(Uri album_art) {
    this.album_art = album_art;
}

public long getDuration() {
    return duration;
}

public void setDuration(long duration) {
    this.duration = duration;
}

any reason y it is getting crashed i add it in the constructor also.


Solution

  • Basically Gson builds the data object from json by using java reflection. It needs an empty constructor. You are using Uri inside your data object. So just save address from Uri as string. That will solve the problem.