簡體   English   中英

為什么checkSelfPermission()拋出NullPointerException

[英]Why checkSelfPermission() is throwing a NullPointerException

按下列表視圖中的call button時,我正在檢查電話呼叫權限。 由於某種原因,我在checkSelfPermission()方法中作為參數傳遞的Context導致了空指針異常。 我已經使用過thisActivityName.thisgetContext()getApplicationContext() 他們都沒有為我工作。

注意:在我按下列表視圖按鈕時,從我的適配器類啟動對makephonecall()方法的調用。

public void makephonecall()
    {
        try {
            if (ContextCompat.checkSelfPermission(BloodVaultActivity2.this,
                    Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {

                ActivityCompat.requestPermissions(BloodVaultActivity2.this,
                        new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CALL);
            } else {
                Intent intent = new Intent(Intent.ACTION_CALL);
                intent.setData(Uri.parse("tel:" + number));
                startActivity(intent);
            }
        }
        catch (NullPointerException e){
            e.printStackTrace();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        if(requestCode == REQUEST_CALL)
        {
            if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                makephonecall();
            }
            else
            {
                Toast.makeText(getApplicationContext(), "Permission Denied", Toast.LENGTH_SHORT).show();
            }
        }
    }


適配器類:

package bd.edu.bubt.regup;

import android.*;
import android.Manifest;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

public class BloodVaultAdapter extends ArrayAdapter<BloodVaultItem> {

    ArrayList<BloodVaultItem> adapterlist = new ArrayList<>();
    int REQUEST_CALL = 1;

    public BloodVaultAdapter(Context context, int textViewResourceId, ArrayList<BloodVaultItem> objects){

        super(context, textViewResourceId, objects);
        adapterlist = objects;
    }

    @Override
    public int getCount(){

        return super.getCount();
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent){

        View v = convertView;
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.blood_vault_list_view_layout, null);

        TextView name = (TextView) v.findViewById(R.id.name);
        TextView group = (TextView) v.findViewById(R.id.group);
        Button call = (Button) v.findViewById(R.id.call);

        call.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                BloodVaultItem bloodVaultItem = getItem(position);

                String number = bloodVaultItem.getContact();

                BloodVaultActivity2 bloodVaultActivity2 = new BloodVaultActivity2();
                bloodVaultActivity2.number = number;
                bloodVaultActivity2.makephonecall();
            }
        });

        name.setText("Name: " +adapterlist.get(position).getName());
        group.setText("Blood Group: " +adapterlist.get(position).getGroup());

        return v;
    }
}


logcat的:

06-13 01:42:36.920 13102-13102/bd.edu.bubt.regup W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.Context.checkPermission(java.lang.String, int, int)' on a null object reference
06-13 01:42:36.921 13102-13102/bd.edu.bubt.regup W/System.err:     at android.support.v4.content.ContextCompat.checkSelfPermission(ContextCompat.java:430)
06-13 01:42:36.921 13102-13102/bd.edu.bubt.regup W/System.err:     at bd.edu.bubt.regup.BloodVaultActivity2.makephonecall(BloodVaultActivity2.java:182)
06-13 01:42:36.921 13102-13102/bd.edu.bubt.regup W/System.err:     at bd.edu.bubt.regup.BloodVaultAdapter$1.onClick(BloodVaultAdapter.java:63)
06-13 01:42:36.921 13102-13102/bd.edu.bubt.regup W/System.err:     at android.view.View.performClick(View.java:5637)
06-13 01:42:36.921 13102-13102/bd.edu.bubt.regup W/System.err:     at android.view.View$PerformClick.run(View.java:22429)
06-13 01:42:36.921 13102-13102/bd.edu.bubt.regup W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
06-13 01:42:36.922 13102-13102/bd.edu.bubt.regup W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
06-13 01:42:36.922 13102-13102/bd.edu.bubt.regup W/System.err:     at android.os.Looper.loop(Looper.java:154)
06-13 01:42:36.922 13102-13102/bd.edu.bubt.regup W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6119)
06-13 01:42:36.922 13102-13102/bd.edu.bubt.regup W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
06-13 01:42:36.922 13102-13102/bd.edu.bubt.regup W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
06-13 01:42:36.922 13102-13102/bd.edu.bubt.regup W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
06-13 01:42:36.928 1382-1455/? W/audio_hw_generic: Not supplying enough data to HAL, expected position 137954329 , only wrote 137954160
06-13 01:42:36.975 1382-1455/? W/audio_hw_generic: Hardware backing HAL too slow, could only write 0 of 720 frames
06-13 01:42:40.154 1382-1456/? W/audio_hw_generic: Not supplying enough data to HAL, expected position 138261974 , only wrote 138108960
06-13 01:43:28.433 2223-8977/com.google.android.apps.nexuslauncher I/ClearcutLoggerApiImpl: disconnect managed GoogleApiClient
01-01 00:00:00.000 0-0/? E/Internal: device offline

嘗試傳遞context (在Adapter的構造函數中接收)代替BloodVaultActivity2.this

ContextCompat.checkSelfPermission(context,Manifest.permission.CALL_PHONE)

另外,BloodVaultActivity2 bloodVaultActivity2 = new BloodVaultActivity2(); 調用方法的方法不正確,因為這將創建您的活動的新實例,而將您的context BloodVaultActivity2BloodVaultActivity2並將this從您的Activity中傳遞給Adapter的構造函數:

if(mContext instanceof YourActivityName){
       ((YourActivityName)mContext).yourActivityMethod();
}

在Activity和Adapter之間進行交互的更好方法是使用接口。 https://android.jlelse.eu/click-listener-for-recyclerview-adapter-2d17a6f6f6c9

更新 :根本原因是您在單擊項目時創建活動的新實例,因此看到空指針。 由於您已經在適配器中傳遞了上下文,因此請按照Manoj在https://stackoverflow.com/a/56573418/3318025中顯示的方式進行操作

如果您使用創建類的對象

BloodVaultActivity2 bloodVaultActivity2 = new BloodVaultActivity2();
            bloodVaultActivity2.number = number;
            bloodVaultActivity2.makephonecall();

它不會調用該函數,因為它是一個具有生命周期感知方法的活動類,所以一種方法是創建一個使用上下文調用該函數的接口,或者將上下文轉換為具有您要運行的方法的活動。喜歡,

   public class BloodVaultAdapter extends ArrayAdapter<BloodVaultItem> {
   Context context;

   public BloodVaultAdapter(Context context, int textViewResourceId, 
   ArrayList<BloodVaultItem> objects){
    super(context, textViewResourceId, objects);
    this.context=context;
    adapterlist = objects;
}

然后,

call.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            BloodVaultItem bloodVaultItem = getItem(position);

            String number = bloodVaultItem.getContact();
            (( BloodVaultActivity2)context).makephonecall();
        }
    });

終於我找到了解決這個問題的方法。 我只是根據他們的答案link1link2組合了AsthaManoj的解決方案。


首先,我使用以下命令捕獲了adapter類的context

Context context;

    public BloodVaultAdapter(Context context, int textViewResourceId, ArrayList<BloodVaultItem> objects){

        super(context, textViewResourceId, objects);
        this.context = context;
        adapterlist = objects;
    }


adapter類第二次將該context作為makephonecallmethod()的參數傳遞:

call.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                BloodVaultItem bloodVaultItem = getItem(position);

                String number = bloodVaultItem.getContact();

                BloodVaultActivity2 bloodVaultActivity2 = new BloodVaultActivity2();
                bloodVaultActivity2.number = number;
                bloodVaultActivity2.makephonecall(context);
            }
        });


第三,使用傳遞的context作為Activity類中的checkSelfPermission()的參數:

Context mcontext;

public void makephonecall(Context context)
    {
        this.mcontext = context;

        try {
            if (ContextCompat.checkSelfPermission(context,
                    Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {

                ActivityCompat.requestPermissions(BloodVaultActivity2.this,
                        new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CALL);
            } else {
                String dial = "tel:" + number;
                context.startActivity(new Intent(Intent.ACTION_CALL, Uri.parse(dial)));
            }
        }
        catch (NullPointerException e){
            e.printStackTrace();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        if(requestCode == REQUEST_CALL)
        {
            if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                makephonecall(mcontext);
            }
            else
            {
                Toast.makeText(getApplicationContext(), "Permission Denied", Toast.LENGTH_SHORT).show();
            }
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM