【问题标题】:onRequestPermissionsResult() does not finish before onViewCreated() conductonRequestPermissionsResult() 在 onViewCreated() 执行之前没有完成
【发布时间】:2025-12-23 02:20:11
【问题描述】:

公共类 PdfRendererBasicFragment 扩展 Fragment 实现 View.OnClickListener {

/**
 * Key string for saving the state of current page index.
 */
private static final String STATE_CURRENT_PAGE_INDEX = "current_page_index";
public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 2;

/**
 * File descriptor of the PDF.
 */


/**
 * {@link android.graphics.pdf.PdfRenderer} to render the PDF.
 */
private PdfRenderer mPdfRenderer;

/**
 * Page that is currently shown on the screen.
 */
private PdfRenderer.Page mCurrentPage;

/**
 * {@link android.widget.ImageView} that shows a PDF page as a {@link android.graphics.Bitmap}
 */
private ImageView mImageView;

/**
 * {@link android.widget.Button} to move to the previous page.
 */
private Button mButtonPrevious;

/**
 * {@link android.widget.Button} to move to the next page.
 */
private Button mButtonNext;


private Bundle copySavedInstanceState;


public PdfRendererBasicFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_pdf_renderer_basic, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    // Retain view references.
    mImageView = (ImageView) view.findViewById(R.id.image);
    mButtonPrevious = (Button) view.findViewById(R.id.previous);
    mButtonNext = (Button) view.findViewById(R.id.next);
    // Bind events.
    mButtonPrevious.setOnClickListener(this);
    mButtonNext.setOnClickListener(this);
    mImageView.setOnClickListener(this);

    copySavedInstanceState = savedInstanceState;


    while (true) {

        int rc = ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);

        if (rc == PackageManager.PERMISSION_GRANTED)
            break;
    }
    // Show the first page by default.
    int index = 0;
    // If there is a savedInstanceState (screen orientations, etc.), we restore the page index.
    if (null != copySavedInstanceState) {
        index = copySavedInstanceState.getInt(STATE_CURRENT_PAGE_INDEX, 0);
    }

    Log.d("check","index : " + index);

    showPage(index);


}


@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    int rc = ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (rc == PackageManager.PERMISSION_GRANTED) {
        try {
            openRenderer(activity);

        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(activity, "Error! " + e.getMessage(), Toast.LENGTH_SHORT).show();
            activity.finish();
        }
    } else {
        requestExternalStoragePermission();
    }
}


@Override
public void onDetach() {
    try {
        closeRenderer();
    } catch (IOException e) {
        e.printStackTrace();
    }
    super.onDetach();
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if (null != mCurrentPage) {
        outState.putInt(STATE_CURRENT_PAGE_INDEX, mCurrentPage.getIndex());
    }
}

private void requestExternalStoragePermission() {

    final String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};

    if (!ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
        ActivityCompat.requestPermissions(getActivity(), permissions, EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
        return;
    }

    final Activity thisActivity = getActivity();

    View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            ActivityCompat.requestPermissions(thisActivity, permissions,
                    EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
        }
    };

}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    if (requestCode != EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE) {
        Log.d("TAG", "Got unexpected permission result: " + requestCode);
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        return;
    }

    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        Log.d("TAG", "Camera permission granted - initialize the camera source");

        // we have permission, so can read SD Card now.
        try {
            openRenderer(getActivity());

        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getActivity(), "Error! " + e.getMessage(), Toast.LENGTH_SHORT).show();
            getActivity().finish();
        }

        return;
    }

    Log.e("TAG", "Permission not granted: results len = " + grantResults.length +
            " Result code = " + (grantResults.length > 0 ? grantResults[0] : "(empty)"));

    DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {

        }
    };

}

/**
 * Sets up a {@link android.graphics.pdf.PdfRenderer} and related resources.
 */
private void openRenderer(Context context) throws IOException {

    File file = new File("/sdcard/Download/test.pdf");
    mPdfRenderer = new PdfRenderer(ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY));


}

/**
 * Closes the {@link android.graphics.pdf.PdfRenderer} and related resources.
 *
 * @throws java.io.IOException When the PDF file cannot be closed.
 */
private void closeRenderer() throws IOException {
    if (null != mCurrentPage) {
        mCurrentPage.close();
    }
    mPdfRenderer.close();

}

/**
 * Shows the specified page of PDF to the screen.
 *
 * @param index The page index.
 */
private void showPage(int index) {
    if (mPdfRenderer.getPageCount() <= index) {
        return;
    }
    // Make sure to close the current page before opening another one.
    if (null != mCurrentPage) {
        mCurrentPage.close();
    }
    // Use `openPage` to open a specific page in PDF.
    mCurrentPage = mPdfRenderer.openPage(index);
    // Important: the destination bitmap must be ARGB (not RGB).
    Bitmap bitmap = Bitmap.createBitmap(mCurrentPage.getWidth(), mCurrentPage.getHeight(),
            Bitmap.Config.ARGB_8888);
    // Here, we render the page onto the Bitmap.
    // To render a portion of the page, use the second and third parameter. Pass nulls to get
    // the default result.
    // Pass either RENDER_MODE_FOR_DISPLAY or RENDER_MODE_FOR_PRINT for the last parameter.
    mCurrentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
    // We are ready to show the Bitmap to user.
    mImageView.setImageBitmap(bitmap);
    updateUi();
}

/**
 * Updates the state of 2 control buttons in response to the current page index.
 */
private void updateUi() {
    int index = mCurrentPage.getIndex();
    int pageCount = mPdfRenderer.getPageCount();
    mButtonPrevious.setEnabled(0 != index);
    mButtonNext.setEnabled(index + 1 < pageCount);
    getActivity().setTitle(getString(R.string.app_name_with_index, index + 1, pageCount));
}

/**
 * Gets the number of pages in the PDF. This method is marked as public for testing.
 *
 * @return The number of pages.
 */
public int getPageCount() {
    return mPdfRenderer.getPageCount();
}

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.previous: {
            // Move to the previous page
            showPage(mCurrentPage.getIndex() - 1);
            break;
        }
        case R.id.next: {
            // Move to the next page
            Log.d("name", mCurrentPage.getIndex() + "");
            showPage(mCurrentPage.getIndex() + 1);
            break;

        }
        case R.id.image: {
            Log.d("name", mCurrentPage.getIndex() + "");
            break;
        }


    }
}

}

嗨,这是我的代码。

我尝试修复。但进展并不顺利。

问题是这样的。

当我执行这个应用程序时。 Android 请求权限,我同意。

但当时 android 在 'openRenderer(activity)' 完成之前执行 'onViewCreated(View view, Bundle savedInstanceState)' 方法。 所以 'showPage(index)' 会引发一些错误。然后(我的意思是权限已经批准,并再次执行)应用程序运行良好。

但我想解决这个问题。

我觉得

第一次,onAttach(Activity activity)执行 并在获得许可后, onAttach(活动活动)和 onViewCreated(查看视图,捆绑 savedInstanceState) 方法似乎同时运行。

请给我建议。

谢谢。

【问题讨论】:

  • 我尝试定位 showPage(index);在 openRenderer(activity); 之后
  • 但它不起作用。
  • 结果出来了。 onRequestPermissionsResult 没有调用。我会检查原因。
  • onRequestPermissionsResult 没有调用,因为我使用了 ActivityCompat.requestPermissions(thisActivity, permissions, EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
  • 使用 requestPermissions(permissions, EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);

标签: android-fragments permissions request


【解决方案1】:
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {

    super.onViewCreated(view, savedInstanceState);
    // Retain view references.
    Log.d("timeStamp", "onViewCreated ");
    mImageView = (ImageView) view.findViewById(R.id.image);
    mButtonPrevious = (Button) view.findViewById(R.id.previous);
    mButtonNext = (Button) view.findViewById(R.id.next);
    // Bind events.
    mButtonPrevious.setOnClickListener(this);
    mButtonNext.setOnClickListener(this);
    mImageView.setOnClickListener(this);


    Log.d("timeStamp", "onViewCreated 할당완료");


    while (true) {
        int rc = getActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);

        if (rc == PackageManager.PERMISSION_GRANTED){
            try {
                openRenderer(getActivity());

            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(getActivity(), "Error! " + e.getMessage(), Toast.LENGTH_SHORT).show();
                getActivity().finish();
            }
            break;
        }


        Log.d("timeStamp", "얼마나 기다리는겨");
    }


    // Show the first page by default.
    int index = 0;
    // If there is a savedInstanceState (screen orientations, etc.), we restore the page index.
    if (null != savedInstanceState) {
        index = savedInstanceState.getInt(STATE_CURRENT_PAGE_INDEX, 0);
    }

    Log.d("timeStamp", "showPage 호출 직전");

    showPage(index);


}

}

我避免了这个问题来添加这个代码。

 while (true) {
    int rc = getActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (rc == PackageManager.PERMISSION_GRANTED){
        try {
            openRenderer(getActivity());

        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getActivity(), "Error! " + e.getMessage(), Toast.LENGTH_SHORT).show();
            getActivity().finish();
        }
        break;
    }


    Log.d("timeStamp", "얼마나 기다리는겨");
}

但是。这不是最好的。

我认为这是因为 onAttach 方法调用 requestPermissions 方法并结束。 onViewCreated 在用户回答请求和调用 onRequestPermissionsResult 之前开始(所以 openRenderer 开始)。

所以我暂停 showPage 方法直到 PERMISSION_GRANTED。

【讨论】:

    最近更新 更多