Android 程序崩溃空指针异常
Android Program Crashing NullPoint Exception
嘿,我花了几个小时尝试解决这个问题,并广泛检查了很多其他问题,试图解决这个问题。
所以在我的 Main Activity 中,我有两个活动,要么从图库中抓取图像,要么是照片,具体取决于按钮
public void DoTakePhoto(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, TAKE_PICTURE);
}
}
public void DoShowSelectImage(View v) {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, SELECT_PICTURE);
}
所以我知道问题类似于我的 onActivityResult 数据似乎为空 我尝试使用 super 找回丢失的 activity 或检查数据是否为空
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SELECT_PICTURE || requestCode == TAKE_PICTURE && null != data) {
if (resultCode == RESULT_OK && null != data) {
Uri selectedimage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedimage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
mImageFullPathAndName = cursor.getString(columnIndex);
cursor.close();
jobID = "";
File file = new File(mImageFullPathAndName);
Bitmap mCurrentSelectedBitmap = decodeFile(file);
if (mCurrentSelectedBitmap != null) {
ivSelectedImg.setImageBitmap(mCurrentSelectedBitmap);
int w = mCurrentSelectedBitmap.getWidth();
int h = mCurrentSelectedBitmap.getHeight();
int length = (w > h) ? w : h;
if (length > OPTIMIZED_LENGTH) {
float ratio = (float) w / h;
int newW, newH = 0;
if (ratio > 1.0) {
newW = OPTIMIZED_LENGTH;
newH = (int) (OPTIMIZED_LENGTH / ratio);
} else {
newH = OPTIMIZED_LENGTH;
newW = (int) (OPTIMIZED_LENGTH * ratio);
}
mCurrentSelectedBitmap = rescaleBitmap(mCurrentSelectedBitmap, newW, newH);
}
mImageFullPathAndName = SaveImage(mCurrentSelectedBitmap);
}
}
}
}
所以我的错误
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.example.zola.capchem/com.example.zola.capchem.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
我已经尝试了这个网站上的大部分内容,但应用程序仍然崩溃。不知道在这里做什么。
如果您尝试从相机拍照,您的代码将会崩溃。
通过相机拍照和从gallery/file系统获取照片的方法是完全不同的。
为了同时执行这两项操作,您需要使用一个 ACTION 和一些附加功能来触发一个意图。您使用此意图为结果启动 activity。结果通过传递给它的意图在 onActivityResult() 中返回给您。
但是,两种情况下返回的意图中存储的结果是不同的。
1) 通过相机拍摄照片:所拍摄图像的位图本身作为 intent bundle 中的额外内容返回给您。您可以通过以下方式访问它:
Bundle extras = data.getExtras();
Bitmap bitmap = (Bitmap) extras.get("data");
//use bitmap however you like...
2) Select 来自画廊的照片:您可能会或可能不会获得 selected 图像的 URI(通过 data.getUri())。如果您获得 URI,则可以通过该 URI 获取您的图像。但是,有时此 uri 可能为空,在这种情况下,android 系统选择将图像写入您在启动 activity 结果时作为额外意图传递的图像 URI。
因此,首先,定义一个临时 URI 并使用它从图库中启动 activity 到 select 图像:
private URI getTempFile()
{
if (isExternalStorageWritable())
{
File file = new File(Environment.getExternalStorageDirectory(), "temporary_file.jpg");
try
{
if(!file.exists())
{
file.createNewFile();
}
} catch (IOException e)
{
}
return Uri.fromFile(file);
} else
{
return null;
}
}
public void DoShowSelectImage(View v) {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
i.putExtra(MediaStore.EXTRA_OUTPUT, getTempFile());
startActivityForResult(i, SELECT_PICTURE);
}
在你的 onActivityResult 中:
Uri selectedimage = data.getData();
if(selectedimage == null)
{
selectedimage = getTempFile();
}
您需要在 onActivityResult 中分别处理这两种情况:
if(result == RESULT_OK && data != null)
{
Bitmap mCurrentSelectedBitmap;
if(requestCode == SELECT_PICTURE)
{
Uri selectedimage = data.getData();
if(selectedimage == null)
{
selectedimage = getTempFile();
}
......
......
mCurrentSelectedBitmap = decodeFile(file);
}
else if(requestCode == TAKE_PICTURE)
{
Bundle extras = data.getExtras();
mCurrentSelectedBitmap = (Bitmap) extras.get("data");
}
.......
.......
//Do your thing
}
注意:您可能需要在清单中添加写入外部存储的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
嘿,我花了几个小时尝试解决这个问题,并广泛检查了很多其他问题,试图解决这个问题。
所以在我的 Main Activity 中,我有两个活动,要么从图库中抓取图像,要么是照片,具体取决于按钮
public void DoTakePhoto(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, TAKE_PICTURE);
}
}
public void DoShowSelectImage(View v) {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, SELECT_PICTURE);
}
所以我知道问题类似于我的 onActivityResult 数据似乎为空 我尝试使用 super 找回丢失的 activity 或检查数据是否为空
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SELECT_PICTURE || requestCode == TAKE_PICTURE && null != data) {
if (resultCode == RESULT_OK && null != data) {
Uri selectedimage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedimage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
mImageFullPathAndName = cursor.getString(columnIndex);
cursor.close();
jobID = "";
File file = new File(mImageFullPathAndName);
Bitmap mCurrentSelectedBitmap = decodeFile(file);
if (mCurrentSelectedBitmap != null) {
ivSelectedImg.setImageBitmap(mCurrentSelectedBitmap);
int w = mCurrentSelectedBitmap.getWidth();
int h = mCurrentSelectedBitmap.getHeight();
int length = (w > h) ? w : h;
if (length > OPTIMIZED_LENGTH) {
float ratio = (float) w / h;
int newW, newH = 0;
if (ratio > 1.0) {
newW = OPTIMIZED_LENGTH;
newH = (int) (OPTIMIZED_LENGTH / ratio);
} else {
newH = OPTIMIZED_LENGTH;
newW = (int) (OPTIMIZED_LENGTH * ratio);
}
mCurrentSelectedBitmap = rescaleBitmap(mCurrentSelectedBitmap, newW, newH);
}
mImageFullPathAndName = SaveImage(mCurrentSelectedBitmap);
}
}
}
}
所以我的错误
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.example.zola.capchem/com.example.zola.capchem.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
我已经尝试了这个网站上的大部分内容,但应用程序仍然崩溃。不知道在这里做什么。
如果您尝试从相机拍照,您的代码将会崩溃。
通过相机拍照和从gallery/file系统获取照片的方法是完全不同的。
为了同时执行这两项操作,您需要使用一个 ACTION 和一些附加功能来触发一个意图。您使用此意图为结果启动 activity。结果通过传递给它的意图在 onActivityResult() 中返回给您。
但是,两种情况下返回的意图中存储的结果是不同的。
1) 通过相机拍摄照片:所拍摄图像的位图本身作为 intent bundle 中的额外内容返回给您。您可以通过以下方式访问它:
Bundle extras = data.getExtras();
Bitmap bitmap = (Bitmap) extras.get("data");
//use bitmap however you like...
2) Select 来自画廊的照片:您可能会或可能不会获得 selected 图像的 URI(通过 data.getUri())。如果您获得 URI,则可以通过该 URI 获取您的图像。但是,有时此 uri 可能为空,在这种情况下,android 系统选择将图像写入您在启动 activity 结果时作为额外意图传递的图像 URI。 因此,首先,定义一个临时 URI 并使用它从图库中启动 activity 到 select 图像:
private URI getTempFile()
{
if (isExternalStorageWritable())
{
File file = new File(Environment.getExternalStorageDirectory(), "temporary_file.jpg");
try
{
if(!file.exists())
{
file.createNewFile();
}
} catch (IOException e)
{
}
return Uri.fromFile(file);
} else
{
return null;
}
}
public void DoShowSelectImage(View v) {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
i.putExtra(MediaStore.EXTRA_OUTPUT, getTempFile());
startActivityForResult(i, SELECT_PICTURE);
}
在你的 onActivityResult 中:
Uri selectedimage = data.getData();
if(selectedimage == null)
{
selectedimage = getTempFile();
}
您需要在 onActivityResult 中分别处理这两种情况:
if(result == RESULT_OK && data != null)
{
Bitmap mCurrentSelectedBitmap;
if(requestCode == SELECT_PICTURE)
{
Uri selectedimage = data.getData();
if(selectedimage == null)
{
selectedimage = getTempFile();
}
......
......
mCurrentSelectedBitmap = decodeFile(file);
}
else if(requestCode == TAKE_PICTURE)
{
Bundle extras = data.getExtras();
mCurrentSelectedBitmap = (Bitmap) extras.get("data");
}
.......
.......
//Do your thing
}
注意:您可能需要在清单中添加写入外部存储的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />