错误提示:Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
出现场景:在实现拼图游戏App中选择相册中图片作为拼图背景时,App闪退报错。
出现原因:通过分析错误提示,
newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
由.Bitmap.getWidth()为空->找到传入的bitmap为空->向上寻找bitmap->最终发现是由于没有对SD卡权限进行申请引起的。
解决方法:
前提:点击‘本地图片’按钮进行选择相册图片
对‘本地图片’按钮设置监听,在onClick方法中,需要进行运行时权限处理,动态申请WRITE_EXTERNAL_STORAGE这个危险权限。原因:相册中的照片都是存储在SD卡上的,我们要从SD卡中读取照片就需要申请这个权限。WRITE_EXTERNAL_STORAGE表示同时授予程序对SD卡读和写的能力。
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("选择:");
builder.setItems(mCustomItems, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (0 == which){
// 本地图册
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){//判断用户是否已经授权
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);//向用户申请授权。
}else {
openAlbum();
}
分析代码:
判断用户是否已经授权,借助的是:ContextCompat.checkSelfPermission(Context, 具体的权限名jian将返回值与PackageManager.PERMISSION_GRANTED作比较,相等说明用户已经授权,不等表示没授权。
ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED
没有授权:调用ActivityCompat.requestPermissions(Activity的实例,String数组(将申请的权限名放入),参数请求码(1))方法向用户申请授权。
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
调用完requestPermissions()方法,系统会弹出一个权限申请对话框,用户可以选择同意或拒绝我们的权限申请,
无论哪种结果,最终都会回调到onRequestPermissionsResult()方法,此方法中授权结果会封装到grantResults参数中。
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode){
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
openAlbum();
}else {
Toast.makeText(this,"You denied the permission",Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
openAlbum()方法:打开相册程序选择照片
private void openAlbum(){
Intent intent = new Intent(Intent.ACTION_PICK, null);//选择数据
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,IMAGE_TYPE);
startActivityForResult(intent, RESULT_IMAGE);//打开相册程序选择照片
}
更改后可以将相册中的图片正常显示作为拼图背景。