当我点击android上的CheckData button
时,它会抛出一个nullpointer exception
。
SaveData.java
public class SaveData extends Activity implements OnClickListener {
static final int DIALOG_ID = 0;
private Uri mImageCaptureUri;
private ImageView mImageView;
public static class Certificates {
private Bitmap bmp;
public Certificates(Bitmap b) {
bmp = b;
}
public Bitmap getBitmap() { return bmp; }
}
private static final int PICK_FROM_CAMERA = 1;
private static final int PICK_FROM_FILE = 2;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.addname);
View button1Click=findViewById(R.id.btn_choose);
button1Click.setOnClickListener(this);
View button2Click = findViewById(R.id.Button01add);
button2Click.setOnClickListener(this);
View button3Click = findViewById(R.id.Button01check);
button3Click.setOnClickListener(this);
}
public void onClick(View v){
switch(v.getId()){
case R.id.Button01add:
showDialog(DIALOG_ID);
break;
case R.id.Button01check:
startActivity(new Intent (SaveData.this,CheckData.class));
break;
}
// picking an image from camera or gallery
final String [] items = new String [] {"From Camera", "From SD Card"};
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this, android.R.layout.select_dialog_item,items);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select Image");
builder.setAdapter( adapter, new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dialog, int item ) {
if (item == 0) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory(), "tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
mImageCaptureUri = Uri.fromFile(file);
try {
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
intent.putExtra("return-data", true);
startActivityForResult(intent, PICK_FROM_CAMERA);
} catch (Exception e) {
e.printStackTrace();
}
dialog.cancel();
} else {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_FILE);
}
}
} );
final AlertDialog dialog = builder.create();
mImageView = (ImageView) findViewById(R.id.image1);
((Button) findViewById(R.id.btn_choose)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.show();
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) return;
Bitmap bitmap = null;
String path = "";
if (requestCode == PICK_FROM_FILE) {
mImageCaptureUri = data.getData();
path = getRealPathFromURI(mImageCaptureUri); //from Gallery
if (path == null)
path = mImageCaptureUri.getPath(); //from File Manager
if (path != null)
bitmap = BitmapFactory.decodeFile(path);
} else {
path = mImageCaptureUri.getPath();
bitmap = BitmapFactory.decodeFile(path);
}
mImageView.setImageBitmap(bitmap);
}
public String getRealPathFromURI(Uri contentUri) {
String [] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery( contentUri, proj, null, null,null);
if (cursor == null) return null;
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
protected final Dialog onCreateDialog(final int id) {
Dialog dialog = null;
switch(id) {
case DIALOG_ID:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Information saved successfully ! Add Another Info?")
.setCancelable(false)
.setPositiveButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
SaveData.this.finish();
}
})
.setNegativeButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
dialog = alert;
break;
default:
}
return dialog;
}
// menu option
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.layout.mymenu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.item1) {
Log.d("Option", "Save option is clicked");
}
if(item.getItemId() == R.id.item2) {
Log.d("Option", "Delete option is clicked");
}
if(item.getItemId() == R.id.item3) {
Log.d("Option", "Exit option is clicked");
}
return super.onOptionsItemSelected(item);
}
}
DataManipulator.java:
public class DataManipulator {
public static final String KEY_IMG = "image";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
private static final String DATABASE_NAME = "DBtest";
private static final int DATABASE_VERSION = 1;
private static final String CERTIFICATES_TABLE = "certificates";
private static final String CREATE_CERTIFICATES_TABLE = "create table "+CERTIFICATES_TABLE+" (" +KEY_IMG+" blob not null) ";
private final Context mCtx;
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_CERTIFICATES_TABLE);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+CERTIFICATES_TABLE);
onCreate(db);
}
}
public void Reset() { mDbHelper.onUpgrade(this.mDb, 1, 1); }
public DataManipulator(Context ctx) {
mCtx = ctx;
mDbHelper = new DatabaseHelper(mCtx);
}
public DataManipulator open() throws SQLException {
mDb = mDbHelper.getWritableDatabase();
return this;
}
public void close() { mDbHelper.close(); }
public void createCertificatesEntry(Certificates certificates) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
certificates.getBitmap().compress(Bitmap.CompressFormat.PNG, 100, out);
ContentValues cv = new ContentValues();
cv.put(KEY_IMG, out.toByteArray());
mDb.insert(CERTIFICATES_TABLE, null, cv);
}
public Certificates getFirstCertificatesFromDB() throws SQLException {
Cursor cur = mDb.query(true, CERTIFICATES_TABLE, new String[] {KEY_IMG}, null, null, null, null, null, null);
if(cur.moveToFirst()) {
byte[] blob = cur.getBlob(cur.getColumnIndex(KEY_IMG));
ByteArrayInputStream inputStream = new ByteArrayInputStream(blob);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
cur.close();
return new Certificates(bitmap);
}
cur.close();
return null;
}
}
DataManipulator.java:60 是certificates.getBitmap().compress(Bitmap.CompressFormat.PNG, 100, out);
CheckData.java:
public class CheckData extends ListActivity {
TextView selection;
DataManipulator dm;
private DataManipulator DataManipulator;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.check);
dm = new DataManipulator(this);
LinearLayout layout = new LinearLayout(this);
ImageView image = new ImageView(this);
DataManipulator = new DataManipulator(this);
Certificates testCertificates = new Certificates(BitmapFactory.decodeFile(Context.STORAGE_SERVICE));
DataManipulator.open();
DataManipulator.createCertificatesEntry( (Certificates) testCertificates);
DataManipulator.close();
testCertificates = null;
DataManipulator.open();
testCertificates = DataManipulator.getFirstCertificatesFromDB();
DataManipulator.close();
image.setImageBitmap(((Certificates) testCertificates).getBitmap());
setContentView(layout);
}
}
CheckData.java:29 是DataManipulator.createCertificatesEntry( (Certificates) testCertificates);
Logcat错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{list.certificates/list.certificates.CheckData}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1955)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980)
at android.app.ActivityThread.access$600(ActivityThread.java:122)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4340)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at list.certificates.DataManipulator.createCertificatesEntry(DataManipulator.java:60)
at list.certificates.CheckData.onCreate(CheckData.java:29)
at android.app.Activity.performCreate(Activity.java:4465)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1919)
答案 0 :(得分:8)
您从certificates.getBitmap()
获得空值,因为那里没有位图。在您的初始分配中,您正在尝试解码不存在的文件。使用Context.STORAGE_SERVICE
不起作用,它只是一个等于storage
的字符串。
例如,如何正确使用存储管理器的代码,请尝试this.
如果您只是尝试解码资源(可绘制,原始等),请使用其他形式的解码:
InputStream is = context.getResources().openRawResource(resID);
Bitmap bitmap = BitmapFactory.decodeStream(is);
<强>更新强>
假设我知道你要做的是什么,问题是你切换到CheckData
活动而没有以任何方式传递选定的位图。活动无法知道要使用的位图,Context.STORAGE_SERVICE
不是任何位图,因此您无法对其进行解码。
有关如何将位图传递给新活动的良好答案,请查看here.
简而言之,您可以向mBitmap
添加SaveData
变量,并将其传递给CheckData
。
为此,请将SaveData.onClick()
中的代码更改为:
case R.id.Button01check:
Intent intent = new Intent (SaveData.this,CheckData.class);
intent.putExtra("bitmapData", mBitmap)
startActivity(intent);
break;
并且,在onActivityResult()
中,最后添加:
mBitmap = bitmap;
在CheckData.onCreate()
:
Bitmap bmp = getIntent().getExtras().get("bitmapData");
if(bmp != null) {
Certificates testCertificates = new Certificates(bmp);
} else {
// Back out gracefully //
}
答案 1 :(得分:2)
你的问题就在这一行
Certificates testCertificates =
new Certificates(BitmapFactory.decodeFile(Context.STORAGE_SERVICE));
decodeFile
的参数无效,因此返回null。该参数应该是图像文件的路径,而您传递的是用于检索存储服务的常量。
您已在SaveData
活动中拥有位图。您需要通过意图将其传递给CheckData
活动。
将位图添加到intent:
case R.id.Button01check:
Intent intent = new Intent(this, CheckData.class);
intent.putExtra("BitmapImage", bitmap);
startActivity(intent);
然后在CheckData
活动中,从intent中检索位图并创建Certificates
对象。
Bitmap bitmap = (Bitmap) getIntent().getParcelableExtra("BitmapImage");
Certificates testCertificates = new Certificates(bitmap );
参考:How can I pass a Bitmap object from one activity to another
答案 2 :(得分:1)
certificates
为null
,或certificates.getBitmap()
正在返回null
。添加日志记录以找出哪个。
答案 3 :(得分:0)
在插入数据之前检查证书是否为空:
public void createCertificatesEntry(Certificates certificates) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
if(certificates !=null)
{
certificates.getBitmap().compress(Bitmap.CompressFormat.PNG, 100, out);
ContentValues cv = new ContentValues();
cv.put(KEY_IMG, out.toByteArray());
mDb.insert(CERTIFICATES_TABLE, null, cv);
}
else
{
}
}
答案 4 :(得分:-1)
一般来说,为了处理异常,我会给你这个提示:
当您在logcat上获得异常时,双击(或按 ENTER)这个块中的每个红色行,直到文本 光标转到您获得异常的正确行。
然后,一旦你知道你得到了哪些变量, 在点击事件和事件发生时,在那里设置一个断点 onCreate,看看为什么你有这个例外。
然而,你的代码有很多奇怪的东西,例如:
为什么要用同一种方法拨打setContentView
两次?
为什么要尝试解码名称为Context.STORAGE_SERVICE
的位图文件?
为什么你有一个具有相同名称的类和实例(DataManipulator
)?请使用更标准的方式命名字段和变量。