[英]Why checkSelfPermission() is throwing a NullPointerException
I'm checking for phone call permission when a call button
in listview is pressed. 按下列表视图中的call button
时,我正在检查电话呼叫权限。 For some reason the Context
I'm passing as a parameter in checkSelfPermission()
method is causing the null pointer exception. 由于某种原因,我在checkSelfPermission()
方法中作为参数传递的Context
导致了空指针异常。 I've used this
, ActivityName.this
, getContext()
, getApplicationContext()
. 我已经使用过this
, ActivityName.this
, getContext()
, getApplicationContext()
。 None of them is working for me. 他们都没有为我工作。
Note: Call to the makephonecall()
method is initiated from my adapter class on listview button pressed. 注意:在我按下列表视图按钮时,从我的适配器类启动对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();
}
}
}
Adapter class: 适配器类:
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: 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
Try passing context
(received in Constructor of Adapter) in place of BloodVaultActivity2.this
ie 尝试传递context
(在Adapter的构造函数中接收)代替BloodVaultActivity2.this
ContextCompat.checkSelfPermission(context,Manifest.permission.CALL_PHONE)
Also, BloodVaultActivity2 bloodVaultActivity2 = new BloodVaultActivity2(); 另外,BloodVaultActivity2 bloodVaultActivity2 = new BloodVaultActivity2(); is incorect way of calling method as this will create new instance of your activity, instead typeCast your context
to BloodVaultActivity2
& pass this
from your Activity in constructor of Adapter : 调用方法的方法不正确,因为这将创建您的活动的新实例,而将您的context
BloodVaultActivity2
到BloodVaultActivity2
并将this
从您的Activity中传递给Adapter的构造函数:
if(mContext instanceof YourActivityName){
((YourActivityName)mContext).yourActivityMethod();
}
Btw a better approach for interaction between Activity & Adapter is using interface. 在Activity和Adapter之间进行交互的更好方法是使用接口。 https://android.jlelse.eu/click-listener-for-recyclerview-adapter-2d17a6f6f6c9 https://android.jlelse.eu/click-listener-for-recyclerview-adapter-2d17a6f6f6c9
Update : The root cause is you are creating a new Instance of the activity on item click, hence you are seeing the null pointer. 更新 :根本原因是您在单击项目时创建活动的新实例,因此看到空指针。 Since you are already passing context in your adapter do it in the way shown by Manoj in https://stackoverflow.com/a/56573418/3318025 由于您已经在适配器中传递了上下文,因此请按照Manoj在https://stackoverflow.com/a/56573418/3318025中显示的方式进行操作
If you create an object of a class using 如果您使用创建类的对象
BloodVaultActivity2 bloodVaultActivity2 = new BloodVaultActivity2();
bloodVaultActivity2.number = number;
bloodVaultActivity2.makephonecall();
It won't call the function, since it is an activity class which has life cycle aware methods, one way is to create an interface invoke the function using context or cast the context to your activity which has the method you want to run Change it like, 它不会调用该函数,因为它是一个具有生命周期感知方法的活动类,所以一种方法是创建一个使用上下文调用该函数的接口,或者将上下文转换为具有您要运行的方法的活动。喜欢,
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;
}
then, 然后,
call.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
BloodVaultItem bloodVaultItem = getItem(position);
String number = bloodVaultItem.getContact();
(( BloodVaultActivity2)context).makephonecall();
}
});
Finally I got a solution for this problem. 终于我找到了解决这个问题的方法。 I just combined the solution of Astha and Manoj from their answers link1 and link2 . 我只是根据他们的答案link1和link2组合了Astha和Manoj的解决方案。
First I caught the context
of my adapter
class using: 首先,我使用以下命令捕获了adapter
类的context
:
Context context;
public BloodVaultAdapter(Context context, int textViewResourceId, ArrayList<BloodVaultItem> objects){
super(context, textViewResourceId, objects);
this.context = context;
adapterlist = objects;
}
Second pass that context
as a parameter of makephonecallmethod()
from adapter
class: 从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);
}
});
Third use the passed context
as a parameter of checkSelfPermission()
inside Activity
class: 第三,使用传递的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.