Android应用程序在模拟器上运行完美,但在真实设备上崩溃

时间:2013-11-12 06:28:36

标签: android eclipse android-emulator runtime-error android-sqlite

            **ISSUE:**

我检查了模拟器数据库正在创建并且应用程序运行正常。但是,当我在这个应用程序运行时单击真实Android设备上的提交按钮时,它强制关闭。 请各位朋友帮忙。代码如下:

  

这是main.xml文件,用户输入信息并点击   提交后,他通过gui输入的值应保存到   数据库中的相应表格。

**Main.xml**
--------


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/editxt_mbno"
        android:textColorHint="@color/BurlyWood"        
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/txt_mbno"
        android:layout_alignBottom="@+id/txt_mbno"
        android:layout_marginLeft="40dp"
        android:layout_toRightOf="@+id/txt_mbno"
        android:ems="10"
        android:hint="@string/edit_mbno" >

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/txt_narrative"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/txt_welcome"
        android:layout_centerHorizontal="true"
        android:text="@string/narrative"
        android:textColor="@color/LimeGreen"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/txt_welcome"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="15dp"
        android:text="@string/welcome"
        android:textColor="@color/red"
        android:textSize="28sp" />

    <EditText
        android:id="@+id/editxt_cloudid"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/sbmt_btn"
        android:layout_alignLeft="@+id/editxt_empid"
        android:ems="10"
        android:hint="@string/edit_cloudid"
        android:textColorHint="@color/BurlyWood" />

    <EditText
        android:id="@+id/editxt_empid"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/editxt_cloudid"
        android:layout_alignLeft="@+id/editxt_clientid"
        android:ems="10"
        android:hint="@string/edit_empid"
        android:textColorHint="@color/BurlyWood" />

    <EditText
        android:id="@+id/editxt_clientid"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/editxt_empid"
        android:layout_alignLeft="@+id/editxt_mbno"
        android:ems="10"
        android:hint="@string/edit_clientid"
        android:textColorHint="@color/BurlyWood" />

    <TextView
        android:id="@+id/txt_employeeid"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/txt_narrative"
        android:layout_alignTop="@+id/editxt_empid"
        android:layout_marginTop="14dp"
        android:text="@string/employee_id"
        android:textColor="@color/Chocolate" />

    <TextView
        android:id="@+id/txt_clientid"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/editxt_clientid"
        android:layout_alignBottom="@+id/editxt_clientid"
        android:layout_alignLeft="@+id/txt_employeeid"
        android:text="@string/client_id"
        android:textColor="@color/Chocolate" />

    <TextView
        android:id="@+id/txt_mbno"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/editxt_clientid"
        android:layout_alignLeft="@+id/txt_clientid"
        android:layout_marginBottom="26dp"
        android:text="@string/mobile_no"
        android:textColor="@color/Chocolate" />

    <Button
        android:id="@+id/sbmt_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_toRightOf="@+id/txt_mbno"
        android:background="@drawable/draw"        
        android:text="@string/btn_txt" />

    <TextView
        android:id="@+id/txt_cloudid"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/editxt_cloudid"
        android:layout_alignBottom="@+id/editxt_cloudid"
        android:layout_alignLeft="@+id/txt_employeeid"
        android:text="@string/cloud_id"
        android:textColor="@color/Chocolate" />

</RelativeLayout>

                                **
  

这是我在代码中用作数据对象的类。基本上   包含getter和setter方法。

Tracking.java
-------------

**

package nice.work.attendance_tracking;

public class Tracking {

    private Long mob_no;
    private String client_id;
    private String emp_id;
    private String cloud_id;

    // adding 5 new fields for testing
    private String datetime;
    private Integer event_id;
    private String event_name;
    private String remarks;
    private String spinner_txt;

    public Long getmobno() {
            return mob_no;
    }

    public void setmobno(long mob_no) {
            this.mob_no = mob_no;
    }

    public String getclientid() {
            return client_id;
    }
    public void setclientid(String client_id) {
            this.client_id = client_id;
    }

    public String getempid() {
        return emp_id;
    }

    public void setempid(String emp_id) {
        this.emp_id = emp_id;
    }

    public String getcloudid() {
            return cloud_id;
    }
    public void setcloudid(String cloud_id) {
            this.cloud_id = cloud_id;
    }
    // added new methods for testing
    public String getdatetime() {
        return datetime;
    }

    public void setdatetime(String datetime) {
        this.datetime = datetime;
    }

    public Integer geteventid() {
        return event_id;
    }

    public void seteventid(int event_id) {
        this.event_id = event_id;
    }

    public String geteventname() {
        return event_name;
    }

    public void seteventname(String event_name) {
        this.event_name = event_name;
    }

    public String getremarks() {
        return remarks;
    }

    public void setremarks(String remarks) {
        this.remarks = remarks;
    }

    public String getspinnertxt() {
        return spinner_txt;
    }

    public void setspinnertxt(String spinner_txt) {
        this.spinner_txt = spinner_txt;
    }
}


                                   **
  

这是主要活动文件,也是第一个获取的活动   由我的申请调用。

MainActivity.java
-----------------

**

package nice.work.attendance_tracking;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener{

      private EditText editmobno;    
      private EditText editclientid;
      private EditText editempid;
      private EditText editcloudid; 
      private Button submit;      
      private ArrayList<Tracking> TrackingObjArrayList;  


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editmobno=(EditText)findViewById(R.id.editxt_mbno);
        editclientid=(EditText)findViewById(R.id.editxt_clientid);
        editempid=(EditText)findViewById(R.id.editxt_empid);
        editcloudid=(EditText) findViewById(R.id.editxt_cloudid);
        submit=(Button)findViewById(R.id.sbmt_btn);
        submit.setOnClickListener(this);

        TrackingObjArrayList = new ArrayList<Tracking>();               
    }

    public void onClick(View v)
    {
        if(v.getId()==R.id.sbmt_btn)
        {
            // Get the values provided by the user via the UI
            Long providedmobno = Long.parseLong(editmobno.getText().toString());
            String providedclientid = editclientid.getText().toString();
            String providedempid = editempid.getText().toString();
            String providedcloudid = editcloudid.getText().toString();

            // Pass above values to the setter methods in POJO class
            Tracking TrackingObj = new Tracking();
            TrackingObj.setmobno(providedmobno);
            TrackingObj.setclientid(providedclientid);
            TrackingObj.setempid(providedempid);
            TrackingObj.setcloudid(providedcloudid);

            // Add an undergraduate with his all details to a ArrayList
            TrackingObjArrayList.add(TrackingObj);

            // Inserting tracking details to the database is doing in a separate method
            insertTracking(TrackingObj);

            // Release from the existing UI and go back to the previous UI
            finish();
            Intent i = new Intent(MainActivity.this,Transaction.class);
            startActivity(i);
     }      
    }

    public void insertTracking(Tracking paraTrackingObj){

        // First we have to open our DbHelper class by creating a new object of that
        AssetDatabaseOpenHelper androidOpenDbHelperObj = new AssetDatabaseOpenHelper(this);

        // Then we need to get a writable SQLite database, because we are going to insert some values
        // SQLiteDatabase has methods to create, delete, execute SQL commands, and perform other common database management tasks.
        SQLiteDatabase sqliteDatabase = androidOpenDbHelperObj.getWritableDatabase();

        // ContentValues class is used to store a set of values that the ContentResolver can process. 
        ContentValues contentValues = new ContentValues();

        // Get values from the Tracking class and passing them to the ContentValues class
        contentValues.put(AssetDatabaseOpenHelper.COLUMN_NAME_MOB_NO, paraTrackingObj.getmobno());
        contentValues.put(AssetDatabaseOpenHelper.COLUMN_NAME_CLIENT_ID, paraTrackingObj.getclientid());
        contentValues.put(AssetDatabaseOpenHelper.COLUMN_NAME_EMPLOYEE_ID, paraTrackingObj.getempid());
        contentValues.put(AssetDatabaseOpenHelper.COLUMN_NAME_CLOUD_ID, paraTrackingObj.getcloudid());

        // Now we can insert the data in to relevant table
        // I am going pass the id value, which is going to change because of our insert method, to a long variable to show in Toast
        long affectedColumnId = sqliteDatabase.insert(AssetDatabaseOpenHelper.TABLE_NAME, null, contentValues);

        // It is a good practice to close the database connections after you have done with it
        sqliteDatabase.close();

        // I am not going to do the retrieve part in this post. So this is just a notification for satisfaction ;-)
        Toast.makeText(this, "Values inserted column ID is :" + affectedColumnId, Toast.LENGTH_SHORT).show();

}

}



                        ** 
  

这是我的数据库活动文件,其中包含所有数据库代码   这将在后端完成。

AssetDatabaseOpenHelper.java
----------------------------

**

package nice.work.attendance_tracking;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;

public class AssetDatabaseOpenHelper extends SQLiteOpenHelper {

    private static final String DB_NAME = "Attendance.sqlite";
    public static final int DB_VERSION = 1;

    // Labels table name
    private static final String TABLE_LABELS = "Event";

 // Labels Table Columns names
   // private static final String KEY_ID = "Event_id";
   // private static final String KEY_NAME = "Event_Name";

    // Table attributes
    public static final String TABLE_NAME = "Param_Value";
    public static final String COLUMN_NAME_MOB_NO = "Mob_no";
    public static final String COLUMN_NAME_CLIENT_ID = "Client_id";
    public static final String COLUMN_NAME_EMPLOYEE_ID = "Emp_id";
    public static final String COLUMN_NAME_CLOUD_ID = "Cloud_id";

    // added additional fields for testing purpose
    public static final String TABLE_NAMES = "Transaction_Table";
    public static final String COLUMN_NAME_DATETIME = "DateTime";
    public static final String COLUMN_NAME_EVENT_ID = "Event_id";
    public static final String COLUMN_NAME_EVENT_NAME = "Event_name";
    public static final String COLUMN_NAME_REMARKS = "Remarks";

    private Context context;

   // public AssetDatabaseOpenHelper(Context context) {
    //    this.context = context;
    //}
    public AssetDatabaseOpenHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
}

    public SQLiteDatabase openDatabase() {
        File dbFile = context.getDatabasePath(DB_NAME);

        if (!dbFile.exists()) {
            try {
                copyDatabase(dbFile);
            } catch (IOException e) {
                throw new RuntimeException("Error creating source database", e);
            }
        }

        return SQLiteDatabase.openDatabase(dbFile.getPath(), null, SQLiteDatabase.OPEN_READONLY);
    }

    private void copyDatabase(File dbFile) throws IOException {
        InputStream is = context.getAssets().open(DB_NAME);
        OutputStream os = new FileOutputStream(dbFile);

        byte[] buffer = new byte[1024];
        while (is.read(buffer) > 0) {
            os.write(buffer);
        }

        os.flush();
        os.close();
        is.close();
    }

    public void onCreate(SQLiteDatabase db) {
        // We need to check whether table that we are going to create is already exists.
        //Because this method get executed every time we created an object of this class. 
        //"create table if not exists TABLE_NAME ( BaseColumns._ID integer primary key autoincrement, FIRST_COLUMN_NAME text not null, SECOND_COLUMN_NAME integer not null);"
        String sqlQueryToCreateTrackingTable = "create table if not exists " + TABLE_NAME + " ( " + BaseColumns._ID + " integer primary key autoincrement, " 
                                                                                                                        + COLUMN_NAME_MOB_NO + " integer not null, "
                                                                                                                        + COLUMN_NAME_CLIENT_ID + " text not null, "
                                                                                                                        + COLUMN_NAME_EMPLOYEE_ID + " text not null, "
                                                                                                                     + COLUMN_NAME_CLOUD_ID + " integer not null);";
        // Execute a single SQL statement that is NOT a SELECT or any other SQL statement that returns data.
        db.execSQL(sqlQueryToCreateTrackingTable);        
}

// onUpgrade method is use when we need to upgrade the database in to a new version
//As an example, the first release of the app contains DB_VERSION = 1
//Then with the second release of the same app contains DB_VERSION = 2
//where you may have add some new tables or alter the existing ones
//Then we need check and do relevant action to keep our pass data and move with the next structure
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if(oldVersion == 1 && newVersion == 2){
                // Upgrade the database
        }                
}

/**
 * Getting all labels
 * returns list of labels
 * */
public List<String> getAllLabels(){
    List<String> labels = new ArrayList<String>();

    // Select All Query
    String selectQuery = "SELECT  * FROM " + TABLE_LABELS;

    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    // looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            labels.add(cursor.getString(1));
        } while (cursor.moveToNext());
    }

    // closing connection
    cursor.close();
    db.close();

    // returning lables
    return labels;
}
}
  

LOGCAT AFTER I RAN APP ON DEVICE AND IT FORCE CLOSED

11-12 11:55:49.880: E/AndroidRuntime(9972): FATAL EXCEPTION: main
11-12 11:55:49.880: E/AndroidRuntime(9972): java.lang.RuntimeException: Unable to start activity ComponentInfo{nice.work.attendance_tracking/nice.work.attendance_tracking.Transaction}: android.database.sqlite.SQLiteException: no such table: Event (code 1): , while compiling: SELECT  * FROM Event
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2306)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2358)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.app.ActivityThread.access$600(ActivityThread.java:156)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1340)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.os.Looper.loop(Looper.java:153)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.app.ActivityThread.main(ActivityThread.java:5297)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at java.lang.reflect.Method.invokeNative(Native Method)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at java.lang.reflect.Method.invoke(Method.java:511)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at dalvik.system.NativeStart.main(Native Method)
11-12 11:55:49.880: E/AndroidRuntime(9972): Caused by: android.database.sqlite.SQLiteException: no such table: Event (code 1): , while compiling: SELECT  * FROM Event
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:886)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:497)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at nice.work.attendance_tracking.AssetDatabaseOpenHelper.getAllLabels(AssetDatabaseOpenHelper.java:116)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at nice.work.attendance_tracking.Transaction.loadSpinnerData(Transaction.java:57)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at nice.work.attendance_tracking.Transaction.onCreate(Transaction.java:43)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.app.Activity.performCreate(Activity.java:5122)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1081)
11-12 11:55:49.880: E/AndroidRuntime(9972):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2270)
11-12 11:55:49.880: E/AndroidRuntime(9972):     ... 11 more

数据库链接: http://d-h.st/JKy

我可以看到在通过eclipse ddms透视图使用模拟器时创建了数据库。 但是当我使用adb shell ls /data/data/nice.work.attendance_tracking/databases/时,即使我的应用程序在模拟器中运行,我总是让设备脱机。

另外,我需要知道我的数据库代码是否有任何问题。但是当我在模拟器上运行应用程序时,值会被保存到我的数据库中。在单击提交时,应用程序强制在真实设备上关闭(之后值应为保存到数据库表)。

1 个答案:

答案 0 :(得分:1)

我认为你应该这样做

String selectQuery = "SELECT  * FROM " + TABLE_LABELS;

而不是

String selectQuery = "SELECT  * FROM " + TABLE_NAME;

检查您的oncreate

String sqlQueryToCreateTrackingTable = "create table if not exists " + TABLE_NAME + " ( " + BaseColumns._ID + " integer primary key autoincrement, " 
                                                                                                                    + COLUMN_NAME_MOB_NO + " integer not null, "
                                                                                                                    + COLUMN_NAME_CLIENT_ID + " text not null, "
                                                                                                                    + COLUMN_NAME_EMPLOYEE_ID + " text not null, "
                                                                                                                 + COLUMN_NAME_CLOUD_ID + " integer not null);";