You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中MyAdapter的onRequestPermissionsResult报错:未覆写父类方法

问题原因分析

你遇到的does not override or implement a method from a supertype错误,核心原因很简单:onRequestPermissionsResult是Activity或Fragment类的专属方法,而你的MyAdapter继承的是BaseAdapter——BaseAdapter根本没有这个方法,所以你用@Override注解去重写它,编译器自然会报错。之前在其他项目里能正常使用,是因为你当时把这个方法写在了Activity类里,而不是Adapter里。

解决方案:把权限回调逻辑移到Activity中

Adapter的职责是负责列表项的渲染和交互触发,权限请求这类和组件生命周期相关的操作,应该交给Activity来处理。我们可以通过接口回调的方式,让Adapter和Activity配合完成权限请求和下载逻辑,具体步骤如下:

1. 在MyAdapter中定义回调接口

用来通知Activity发起权限请求,以及在权限通过后触发下载操作:

public class MyAdapter extends BaseAdapter {
    // 新增回调接口
    public interface PermissionDownloadCallback {
        // 请求存储权限,同时传递当前要下载的参数
        void requestStoragePermission(String fileName, String dirPath, String audioUrl);
        // 权限通过后执行下载
        void onPermissionGranted(String fileName, String dirPath, String audioUrl);
    }

    private static final int PERMISSION_REQUEST_CODE = 1;
    String fileName;
    String dirPath;
    Context context;
    ArrayList<StoryModel> TitleAndImage ;
    ArrayList<StoryModel> forShowEachStoryInNewActivity ;
    LayoutInflater inflter;
    // 新增回调实例
    private PermissionDownloadCallback callback;

    // 修改构造方法,传入回调
    public MyAdapter(Context context, ArrayList<StoryModel> TitleAndImage, ArrayList<StoryModel> forShowEachStoryInNewActivity, PermissionDownloadCallback callback) {
        this.context = context;
        this.TitleAndImage = TitleAndImage;
        this.forShowEachStoryInNewActivity=forShowEachStoryInNewActivity;
        this.callback = callback;
        inflter = LayoutInflater.from(context);
    }

    // ... 原有的getCount、getItem等方法保持不变 ...

    // 修改下载按钮的点击逻辑
    b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dirPath = com.example.abdullah.newstroynory.Utils.getRootDirPath(context);
            String title_For_Download = forShowEachStoryInNewActivity.get(position).getTitle();
            fileName = title_For_Download + ".mp3";
            String audio_For_Download = forShowEachStoryInNewActivity.get(position).getAudio();

            if (Build.VERSION.SDK_INT >= 23) {
                if (checkPermission()) {
                    // 权限已通过,直接触发下载
                    dorDownloadMyAudios(fileName, dirPath, audio_For_Download);
                } else {
                    // 通知Activity发起权限请求,并传递下载参数
                    callback.requestStoragePermission(fileName, dirPath, audio_For_Download);
                }
            } else {
                // 低于23的系统无需权限,直接下载
                dorDownloadMyAudios(fileName, dirPath, audio_For_Download);
            }
        }
    });

    // ... 原有的checkPermission方法保持不变 ...

    // 删除原来的onRequestPermissionsResult方法,因为Adapter里不能重写它

    // 把下载方法改成public,让Activity可以调用
    public void dorDownloadMyAudios(String fileName, String dirPath, String url){
        PRDownloader.initialize(context);
        PRDownloaderConfig config = PRDownloaderConfig.newBuilder()
                .setDatabaseEnabled(true)
                .build();
        PRDownloader.initialize(context, config);
        int downloadId = PRDownloader.download(url, dirPath, fileName)
                .build()
                .setOnStartOrResumeListener(new OnStartOrResumeListener() {
                    @Override
                    public void onStartOrResume() {
                    }
                })
                .setOnPauseListener(new OnPauseListener() {
                    @Override
                    public void onPause() {
                    }
                })
                .setOnProgressListener(new OnProgressListener() {
                    @Override
                    public void onProgress(Progress progress) {
                    }
                })
                .start(new OnDownloadListener() {
                    @Override
                    public void onDownloadComplete() {
                        Toast.makeText(context, "下载完成!", Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onError(Error error) {
                        Toast.makeText(context, "下载失败:" + error.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                });
    }
}

2. 在对应的Activity中实现回调接口

把权限请求和回调逻辑放在Activity里处理:

public class YourStoryActivity extends AppCompatActivity implements MyAdapter.PermissionDownloadCallback {
    private MyAdapter adapter;
    // 暂存要下载的参数,权限通过后使用
    private String pendingFileName;
    private String pendingDirPath;
    private String pendingAudioUrl;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_activity_layout);
        
        // 初始化列表数据(这里替换成你自己的数据源)
        ArrayList<StoryModel> titleAndImageList = new ArrayList<>();
        ArrayList<StoryModel> storyList = new ArrayList<>();
        
        // 创建Adapter时传入当前Activity作为回调
        adapter = new MyAdapter(this, titleAndImageList, storyList, this);
        ListView listView = findViewById(R.id.list_view);
        listView.setAdapter(adapter);
    }

    @Override
    public void requestStoragePermission(String fileName, String dirPath, String audioUrl) {
        // 暂存下载参数
        this.pendingFileName = fileName;
        this.pendingDirPath = dirPath;
        this.pendingAudioUrl = audioUrl;
        
        // 发起权限请求
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            Toast.makeText(this, "存储权限允许我们保存文件,请在设置中开启该权限", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(this, 
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 
                MyAdapter.PERMISSION_REQUEST_CODE);
        }
    }

    @Override
    public void onPermissionGranted(String fileName, String dirPath, String audioUrl) {
        // 权限通过,触发下载
        adapter.dorDownloadMyAudios(fileName, dirPath, audioUrl);
    }

    // 重写Activity的权限回调方法
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == MyAdapter.PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.e("权限状态", "权限已授予,可以使用本地存储");
                // 通知Adapter执行下载
                onPermissionGranted(pendingFileName, pendingDirPath, pendingAudioUrl);
                // 清空暂存参数
                pendingFileName = null;
                pendingDirPath = null;
                pendingAudioUrl = null;
            } else {
                Log.e("权限状态", "权限被拒绝,无法下载文件");
                Toast.makeText(this, "权限被拒绝,无法完成下载", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

这样修改后,权限请求和回调逻辑就完全交给Activity处理,Adapter只负责触发交互和执行下载,既符合Android的设计规范,也能解决你遇到的编译错误。

内容的提问来源于stack exchange,提问作者Abdullah Khudher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:43:14