简体   繁体   中英

java.lang.NoSuchMethodError: No virtual method setDataSource(Landroid/content/res/AssetFileDescriptor;)V in class Landroid/media/MediaPlayer ERROR

I want to play video using textureview..but while running the app,it stops and Im facing the following error.I dont know what to do i tried a lot and spend nearly 8 hours to resolve this issue..but i cant..please help me to get rid of this..

java.lang.NoSuchMethodError: No virtual method setDataSource(Landroid/content/res/AssetFileDescriptor;)V in class Landroid/media/MediaPlayer; or its super classes (declaration of 'android.media.MediaPlayer' appears in /system/framework/framework.jar)
        at com.vcube.textureview.MainActivity.onSurfaceTextureAvailable(MainActivity.java:42)
        at android.view.TextureView.getHardwareLayer(TextureView.java:370)
        at android.view.View.updateDisplayListIfDirty(View.java:14170)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.View.draw(View.java:14985)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3431)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3224)
        at android.view.View.updateDisplayListIfDirty(View.java:14188)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.View.draw(View.java:14985)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3431)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3224)
        at android.view.View.updateDisplayListIfDirty(View.java:14188)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.View.draw(View.java:14985)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3431)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3224)
        at android.view.View.updateDisplayListIfDirty(View.java:14188)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.View.draw(View.java:14985)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3431)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3224)
        at android.view.View.updateDisplayListIfDirty(View.java:14188)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.View.draw(View.java:14985)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3431)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3224)
        at android.view.View.updateDisplayListIfDirty(View.java:14188)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.View.draw(View.java:14985)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3431)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3224)
        at android.view.View.draw(View.java:15260)
        at android.widget.FrameLayout.draw(FrameLayout.java:598)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2731)
        at android.view.View.updateDisplayListIfDirty(View.java:14193)
        at android.view.View.getDisplayList(View.java:14215)
        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:273)
        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:279)
        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:318)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:2628)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2444)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2074)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1116)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6098)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:773)
        at android.view.Choreographer.doCallbacks(Choreographer.java:586)
        at android.view.Choreographer.doFrame(Choreographer.java:556)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:759)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:159)
        at android.app.ActivityThread.main(ActivityThread.java:5461)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)

I included video in asset folder.. I don't know where im wrong..

Following is a java code i used.

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.content.res.AssetFileDescriptor;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.view.Surface;
import android.view.TextureView;


import java.io.IOException;

public class MainActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener {

    private TextureView textureview;
    private MediaPlayer mediaPlayer;

    private AssetFileDescriptor fileDescriptor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textureview = (TextureView) findViewById(R.id.textureView);
        textureview.setSurfaceTextureListener(this);
        mediaPlayer = new MediaPlayer();
        try {
            fileDescriptor = getAssets().openFd("random.mp4");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        Surface surfaceTexture = new Surface(surface);
        try {
            mediaPlayer.setDataSource(fileDescriptor);
            mediaPlayer.setSurface(surfaceTexture);
            mediaPlayer.prepareAsync();
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mediaPlayer.start();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }

    @Override
    protected void onPause() {
        if(mediaPlayer!=null && mediaPlayer.isPlaying()){
            mediaPlayer.pause();
        }
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if(mediaPlayer!=null){
            mediaPlayer.start();
        }
    }

    @Override
    protected void onDestroy() {
        if(mediaPlayer!=null){
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer =null;
        }
        super.onDestroy();
    }
}

can you suggest me any solution pleaseee?? Thanks

setDataSource(AssetFileDescriptor) was only added in API level 24 (Android 7.0). Attempting to call it on an earlier runtime version causes a crash like this.

Annotating your method with @RequiresApi(api = Build.VERSION_CODES.N) just suppresses the "this call requires API level 24, min SDK is 15" lint errors at compile time. It does nothing at runtime. It does make direct callers to get lint checks for API level 24 but since it's an overridden method, it's not getting directly called by any code and there's no errors to the callers.

What to do? You can look at the source for setDataSource(AssetFileDescriptor) eg at https://cs.android.com/android/platform/superproject/+/android-9.0.0_r8:frameworks/base/media/java/android/media/MediaPlayer.java;l=1209 and discover that you can achieve the same functionality with methods available in earlier SDK versions, such as setDataSource(FileDescriptor, long, long) :

public void setDataSource(@NonNull AssetFileDescriptor afd)
        throws IOException, IllegalArgumentException, IllegalStateException {
    Preconditions.checkNotNull(afd);
    // Note: using getDeclaredLength so that our behavior is the same
    // as previous versions when the content provider is returning
    // a full file.
    if (afd.getDeclaredLength() < 0) {
        setDataSource(afd.getFileDescriptor());
    } else {
        setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM