很难看到我开发了我的第一个应用程序且测试版无法在设备上运行。该应用程序将基本上添加图片以及相同的文本详细信息。一个语音记录,以保持一些更生动的信息。在模拟器上,这工作正常,但在设备上失败:-( 请帮忙。
这里是LogCat:
06-19 18:04:33.495: E/SQLiteDatabase(31541): close() was never explicitly called on database '/data/data/com.example.tg_db1/databases/Bengalooru'
06-19 18:04:33.495: E/SQLiteDatabase(31541): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:2063)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1117)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1074)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1161)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:869)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:228)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at com.example.tg_db1.RegistrationAdapter.write(RegistrationAdapter.java:27)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at com.example.tg_db1.RegistrationAdapter.queryName(RegistrationAdapter.java:68)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at com.example.tg_db1.MainActivity.onCreate(MainActivity.java:50)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.app.Activity.performCreate(Activity.java:4533)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1053)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1934)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1995)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.app.ActivityThread.access$600(ActivityThread.java:128)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.os.Handler.dispatchMessage(Handler.java:99)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.os.Looper.loop(Looper.java:137)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at android.app.ActivityThread.main(ActivityThread.java:4517)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at java.lang.reflect.Method.invokeNative(Native Method)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at java.lang.reflect.Method.invoke(Method.java:511)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
06-19 18:04:33.495: E/SQLiteDatabase(31541): at dalvik.system.NativeStart.main(Native Method)
06-19 18:04:33.495: E/System(31541): Uncaught exception thrown by finalizer
06-19 18:04:33.495: E/System(31541): java.lang.IllegalStateException: Don't have database lock!
06-19 18:04:33.495: E/System(31541): at android.database.sqlite.SQLiteDatabase.verifyLockOwner(SQLiteDatabase.java:2221)
06-19 18:04:33.495: E/System(31541): at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2313)
06-19 18:04:33.495: E/System(31541): at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2309)
06-19 18:04:33.495: E/System(31541): at android.util.LruCache.trimToSize(LruCache.java:197)
06-19 18:04:33.495: E/System(31541): at android.util.LruCache.evictAll(LruCache.java:285)
06-19 18:04:33.495: E/System(31541): at android.database.sqlite.SQLiteDatabase.deallocCachedSqlStatements(SQLiteDatabase.java:2274)
06-19 18:04:33.495: E/System(31541): at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:1246)
06-19 18:04:33.495: E/System(31541): at android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java:2034)
06-19 18:04:33.495: E/System(31541): at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:185)
06-19 18:04:33.495: E/System(31541): at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168)
06-19 18:04:33.495: E/System(31541): at java.lang.Thread.run(Thread.java:856)
add_company.java
package com.example.tg_db1;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;
public class add_company extends Activity{
ImageView iv;
Button b1,b2,b3;
EditText et1, et2;
RegistrationAdapter adapter;
RegistrationOpenHelper helper;
private static final int REQUEST_CODE = 1;
private String logopath;
String imgPath = null;
private Bitmap bitmap;
//Adding for voice record
ImageButton play,record,stop;
private String voicerec=null;
MediaPlayer mp;
MediaRecorder mr;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.add_company);
iv = (ImageView)findViewById(R.id.imageView1);
b1 = (Button)findViewById(R.id.button1);
b2 = (Button)findViewById(R.id.button2);
b3 = (Button)findViewById(R.id.button3);
et1 = (EditText)findViewById(R.id.editText1);
et2 = (EditText)findViewById(R.id.editText2);
adapter = new RegistrationAdapter(this);
iv.setImageDrawable(null); //Should be blank before selecting the image
//Adding voice record
play = (ImageButton)findViewById(R.id.Play);
record = (ImageButton)findViewById(R.id.Record);
stop = (ImageButton)findViewById(R.id.Stop);
}
public void browse(View v){
@SuppressWarnings("unused")
int id = v.getId();
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
InputStream stream = null;
if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Uri imgUri = data.getData();
logopath = getPath(imgUri);
//This block is to show the view
try {
if(bitmap != null){
bitmap.recycle();
}
stream = getContentResolver().openInputStream(data.getData());
bitmap = BitmapFactory.decodeStream(stream);
iv.setImageBitmap(Bitmap.createScaledBitmap(bitmap, 150, 150, true));
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
finally{
if (stream != null) {
try {
stream.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
private String getPath(Uri uri) {
String[] projection = {MediaStore.Images.Media.DATA};
@SuppressWarnings("deprecation")
Cursor cursor = managedQuery(uri, projection, null, null, null);
int col_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(col_index);
}
//Adding for voice record
@SuppressWarnings("unused")
public void submit(View v){
String compname = et1.getText().toString();
String address = et2.getText().toString();
logopath = imgFilePath();
long val = adapter.insertDetails(compname, address, logopath, voicerec);
finish();
}
private String imgFilePath() {
File imgFile = null;
try {
imgFile = File.createTempFile("complogo", ".png");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileOutputStream fOut = null;
try {
fOut = new FileOutputStream(imgFile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
imgPath = imgFile.getAbsolutePath();
return imgPath;
}
public void reset(View v){
et1.setText("");
et2.setText("");
iv.setImageDrawable(null); //Image is removed when reset
voicerec = null; //Voice record path set to null
}
public void record(View v){
File audioFile = null;
try {
audioFile = File.createTempFile("voice", ".amr");
} catch (IOException e1) {
e1.printStackTrace();
}
mr = new MediaRecorder();
voicerec = audioFile.getAbsolutePath();
//System.out.println("Path: "+voicerec);
mr.setAudioSource(MediaRecorder.AudioSource.MIC);
mr.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mr.setOutputFile(voicerec);
try{
mr.prepare();
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
Toast.makeText(add_company.this, "Recording", Toast.LENGTH_LONG).show();
mr.start();
}
public void stop(View v){
mr.stop(); //this is stop recording
Toast.makeText(add_company.this, "Stopped", Toast.LENGTH_LONG).show();
mr.reset(); // this is required to avoid the error: Fatal signal 11 (SIGSEGV) at 0x00000010 (code=1)
mr.release();
}
public void play(View v){
try{
File f = new File(voicerec);
Uri u = Uri.fromFile(f);
mp = MediaPlayer.create(add_company.this, u);
mp.setLooping(false);
mp.start();
}
catch(RuntimeException re){
re.printStackTrace();
}
}
}
RegistrationAdapter.java
package com.example.tg_db1;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class RegistrationAdapter {
SQLiteDatabase sdb;
RegistrationOpenHelper helper;
Context context;
public RegistrationAdapter(Context c){
context = c;
}
@SuppressWarnings("static-access")
public RegistrationAdapter read(){
helper = new RegistrationOpenHelper(context, helper.DATABASE_NAME, null, helper.VERSION);
sdb = helper.getReadableDatabase();
return this;
}
@SuppressWarnings("static-access")
public RegistrationAdapter write(){
helper = new RegistrationOpenHelper(context, helper.DATABASE_NAME, null, helper.VERSION);
sdb = helper.getWritableDatabase();
return this;
}
public void close(){
if(sdb!=null)
sdb.close();
}
//Addition for voice
@SuppressWarnings("static-access")
public long insertDetails(String compname, String address, String complogo, String voicerec){
ContentValues cv = new ContentValues();
cv.put(helper.COMP_NAME, compname);
cv.put(helper.COMP_ADDRESS, address);
cv.put(helper.COMP_LOGO, complogo);
cv.put(helper.COMP_VOICE, voicerec);
write();
long val = sdb.insert(helper.TABLE_NAME, null, cv);
close();
return val;
}
@SuppressWarnings("static-access")
public long updateDetail(int rowID, String compname, String address, String complogo, String voicerec){
ContentValues cv = new ContentValues();
cv.put(helper.COMP_NAME, compname);
cv.put(helper.COMP_ADDRESS, address);
cv.put(helper.COMP_LOGO, complogo);
cv.put(helper.COMP_VOICE, voicerec);
write();
long val = sdb.update(helper.TABLE_NAME, cv, helper.KEY_ID + "=" + rowID, null);
close();
return val;
}
@SuppressWarnings("static-access")
public Cursor queryName(){
String[] cols = {helper.KEY_ID, helper.COMP_NAME, helper.COMP_ADDRESS, helper.COMP_LOGO, helper.COMP_VOICE};
write();
Cursor c = sdb.query(helper.TABLE_NAME, cols, null, null, null, null, null);
return c;
}
@SuppressWarnings("static-access")
public Cursor queryAll(int nameID){
String[] cols = {helper.KEY_ID, helper.COMP_NAME, helper.COMP_ADDRESS, helper.COMP_LOGO, helper.COMP_VOICE};
write();
Cursor c = sdb.query(helper.TABLE_NAME, cols, helper.KEY_ID + " = " + nameID, null, null, null, null);
return c;
}
public int deleteDetail(int rowID){
write();
@SuppressWarnings("static-access")
int val = sdb.delete(helper.TABLE_NAME, helper.KEY_ID + "=" + rowID, null);
close();
return val;
}
}
答案 0 :(得分:2)
尝试将此添加到您的代码中
protected void onDestroy() {
super.onDestroy();
if (sdb!= null) {
sdb.close();
}
并在使用后关闭Cursor对象。
希望有所帮助:)
答案 1 :(得分:0)
在onCreate的Application类中打开数据库一次,不要关闭它,但是一旦不需要它就关闭光标。保留静态引用(例如,您的sdb
变量)并直接访问它。
例如:RegistrationAdapter.queryName()
返回一个游标。因此,无论您何时返回光标,请检查使用情况,并在不再使用时立即将其关闭。这应该可以解决问题。
答案 2 :(得分:0)
以下方法会产生问题。
@SuppressWarnings("static-access")
public Cursor queryName(){
String[] cols = {helper.KEY_ID, helper.COMP_NAME, helper.COMP_ADDRESS, helper.COMP_LOGO, helper.COMP_VOICE};
write();
Cursor c = sdb.query(helper.TABLE_NAME, cols, null, null, null, null, null);
return c;
}
@SuppressWarnings("static-access")
public Cursor queryAll(int nameID){
String[] cols = {helper.KEY_ID, helper.COMP_NAME, helper.COMP_ADDRESS, helper.COMP_LOGO, helper.COMP_VOICE};
write();
Cursor c = sdb.query(helper.TABLE_NAME, cols, helper.KEY_ID + " = " + nameID, null, null, null, null);
return c;
}
关闭您使用它们后返回的数据库和光标。