2017-01-13 114 views
0

我正在使用XMLPullParser解析Web服务响应,并且希望将其存储在本地数据库中,以便能够减少网络流量,因为API不是最有效的移动。无法保存对数据库的XML解析响应

我已经创建了数据库类,不知道如何将响应放入数据库,然后使用它获取我的信息我需要填充我的列表视图或再次点击服务以获取更多数据,因为数据库不会'没有。

具有网络呼叫和ListView

public class MainActivity extends AppCompatActivity { 

    ListView tappedListView, directReportListView; 
    ProgressBar mProgressBar; 
    ArrayList<PeepWithPic> mPeepWithPics = new ArrayList<>(); 
    ListViewAdapter mAdapter; 
    DatabaseHandler databaseHandler; 


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

     /* if toolbar is wanted by user uncomment 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar);*/ 

     tappedListView = (ListView) findViewById(R.id.contactListView); 
     directReportListView = (ListView) findViewById(R.id.clickedContactLV); 
     mProgressBar = (ProgressBar) findViewById(R.id.progressBar); 
     mProgressBar.setVisibility(View.VISIBLE); 
     mAdapter = new ListViewAdapter(this, mPeepWithPics); 
     tappedListView.setAdapter(mAdapter); 
     directReportListView.setAdapter(mAdapter); 
     getXMLData(); 

     databaseHandler = new DatabaseHandler(mPeepWithPics); // error is here 
    } 

    //Uncomment to add OptionsMenu(three dots on app bar) if needed 
    /*@Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    }*/ 

    private static OkHttpClient getUnsafeOkHttpClient() { 
     try { 
      // Create a trust manager that does not validate certificate chains 
      final TrustManager[] trustAllCerts = new TrustManager[]{ 
        new X509TrustManager() { 
         @Override 
         public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { 
         } 

         @Override 
         public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { 
         } 

         @Override 
         public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
          return new java.security.cert.X509Certificate[]{}; 
         } 
        } 
      }; 

      // Install the all-trusting trust manager 
      final SSLContext sslContext = SSLContext.getInstance("SSL"); 
      sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); 
      // Create an ssl socket factory with our all-trusting manager 
      final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); 

      OkHttpClient.Builder builder = new OkHttpClient.Builder(); 
      builder.connectTimeout(5, TimeUnit.MINUTES) 
        .writeTimeout(5, TimeUnit.MINUTES) 
        .readTimeout(5, TimeUnit.MINUTES); 
      builder.sslSocketFactory(sslSocketFactory); 
      builder.hostnameVerifier(new HostnameVerifier() { 
       @Override 
       public boolean verify(String hostname, SSLSession session) { 
        return true; 
       } 
      }); 

      return builder.build(); 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 

    public void getXMLData() { 
     OkHttpClient client = getUnsafeOkHttpClient(); 
     Request request = new Request.Builder() 
       .url(getString(R.string.API_FULL_URL)) 
       .build(); 
     client.newCall(request).enqueue(new Callback() { 
      @Override 
      public void onFailure(Call call, IOException e) { 
       e.printStackTrace(); 
      } 

      @Override 
      public void onResponse(Call call, final Response response) throws IOException { 
       final String responseData = response.body().string(); 
       final InputStream stream = new ByteArrayInputStream(responseData.getBytes()); 
       XMLPullParserHandler parserHandler = new XMLPullParserHandler(); 
       final ArrayList<PeepWithPic> peepWithPics = (ArrayList<PeepWithPic>) parserHandler.parse(stream); 
       mPeepWithPics.clear(); 
       mPeepWithPics.addAll(peepWithPics); 


       //tell adapter on the UI thread its data changed 
       runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         mAdapter.notifyDataSetChanged(); 
         tappedListView.setVisibility(View.VISIBLE); 
         directReportListView.setVisibility(View.VISIBLE); 
         mProgressBar.setVisibility(View.GONE); 
        } 
       }); 
      } 
     }); 
    } 

} 

在线路databseHandler =新数据库处理器(mPeepWithPics)我DatabaseHandler.java

public class DatabaseHandler extends SQLiteOpenHelper { 
    private static final int DATABASE_VERSION = 1; 
    private static final String DATABASE_NAME = "contactManager"; 
    private static final String TABLE_CONTACTS = "contacts"; 

    //Contacts table columns names 
    private static final String KEY_ID = "Employee_number"; 
    private static final String KEY_FIRST_NAME = "First_name"; 
    private static final String KEY_LAST_NAME = "Last_name"; 
    private static final String KEY_PHONE_NUMBER_MOBILE = "Phone_mobile"; 
    private static final String KEY_PHONE_NUMBER_OFFICE = "Phone_office"; 
    private static final String KEY_PAYROLL_TITLE = "Payroll_title"; 
    private static final String KEY_HAS_DIRECT_REPORTS = "Has_direct_reports"; 
    private static final String KEY_EMAIL = "Email"; 
    private static final String KEY_COST_CENTER = "Cost_center_id"; 


    public DatabaseHandler(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "(" 
       + KEY_ID + " STRING PRIMARY KEY," + KEY_FIRST_NAME + " TEXT," 
       + KEY_LAST_NAME + " TEXT" 
       + KEY_PHONE_NUMBER_MOBILE + " TEXT" 
       + KEY_PHONE_NUMBER_OFFICE + " TEXT" 
       + KEY_PAYROLL_TITLE + " TEXT" 
       + KEY_HAS_DIRECT_REPORTS + " TEXT" 
       + KEY_EMAIL + " TEXT" 
       + KEY_COST_CENTER + " TEXT" + ")"; 
     db.execSQL(CREATE_CONTACTS_TABLE); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     //drop old table if existence 
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS); 

     //Create table again 
     onCreate(db); 
    } 

    //Add new contact 
    public void addContact(PeepWithPic peepWithPic) { 
     SQLiteDatabase database = this.getWritableDatabase(); 
     ContentValues values = new ContentValues(); 
     values.put(KEY_FIRST_NAME, peepWithPic.getFirst_name()); 
     values.put(KEY_LAST_NAME, peepWithPic.getLast_name()); 
     values.put(KEY_PHONE_NUMBER_MOBILE, peepWithPic.getPhone_mobile()); 
     values.put(KEY_PHONE_NUMBER_OFFICE, peepWithPic.getPhone_office()); 
     values.put(KEY_HAS_DIRECT_REPORTS, peepWithPic.getHas_direct_reports()); 
     values.put(KEY_EMAIL, peepWithPic.getEmail()); 
     values.put(KEY_COST_CENTER, peepWithPic.getCost_center_id()); 

     //Inserting Row 
     database.insert(TABLE_CONTACTS, null, values); 
     database.close(); 
    } 

    //Get single contact 
    public PeepWithPic getContact(int employeeNumber) { 
     SQLiteDatabase database = this.getReadableDatabase(); 

     Cursor cursor = database.query(TABLE_CONTACTS, new String[] { 
       KEY_ID, KEY_FIRST_NAME, KEY_LAST_NAME, KEY_PHONE_NUMBER_OFFICE, KEY_PHONE_NUMBER_MOBILE, 
       KEY_HAS_DIRECT_REPORTS, KEY_EMAIL, KEY_COST_CENTER}, KEY_ID + "=?", 
       new String[]{ String.valueOf(employeeNumber)}, null, null, null, null); 
     if(cursor != null) 
      cursor.moveToFirst(); 

      PeepWithPic peepWithPic = new PeepWithPic(cursor.getString(0), 
        cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4), 
        cursor.getString(5), cursor.getString(6), cursor.getString(7), cursor.getString(8), 
        cursor.getString(9), cursor.getString(10), cursor.getString(11), cursor.getString(12), 
        cursor.getString(12), cursor.getString(14), cursor.getString(15), cursor.getString(16), 
        cursor.getString(17), cursor.getString(18), cursor.getString(19), cursor.getString(20), 
        cursor.getString(21), cursor.getString(22), cursor.getString(23), cursor.getString(24), 
        cursor.getString(24), cursor.getString(25), cursor.getString(26)); 

      return peepWithPic; 
    } 

    //Get All Contacts 
    public List<PeepWithPic> getAllContacts() { 
     List<PeepWithPic> contactList = new ArrayList<>(); 
     //Select all query 
     String selectQuery = "SELECT * FROM " + TABLE_CONTACTS; 

     SQLiteDatabase database = this.getWritableDatabase(); 
     Cursor cursor = database.rawQuery(selectQuery, null); 

     //looping through all rows and adding to list 
     if (cursor.moveToFirst()) { 
      do { 
       PeepWithPic peepWithPic = new PeepWithPic(); 
       peepWithPic.setEmployee_number(cursor.getString(7)); 
       peepWithPic.setFirst_name(cursor.getString(9)); 
       peepWithPic.setLast_name(cursor.getString(11)); 
       peepWithPic.setPhone_office(cursor.getString(19)); 
       peepWithPic.setPhone_mobile(cursor.getString(18)); 
       peepWithPic.setHas_direct_reports(cursor.getString(10)); 
       peepWithPic.setEmail(cursor.getString(6)); 
       peepWithPic.setCost_center_id(cursor.getString(4)); 
      } while (cursor.moveToNext()); 
     } 

     //return contat list 
     return contactList; 
    } 

    //Get contact Count 
    public int getContactCount() { 
     String countQuery = "SELECT * FROM " + TABLE_CONTACTS; 
     SQLiteDatabase database = this.getReadableDatabase(); 
     Cursor cursor = database.rawQuery(countQuery, null); 
     cursor.close(); 

     return cursor.getCount(); 
    } 

    //Updating single contact 
    public int updateContact(PeepWithPic peepWithPic){ 
     SQLiteDatabase database = this.getWritableDatabase(); 

     ContentValues values = new ContentValues(); 
     values.put(KEY_FIRST_NAME, peepWithPic.getFirst_name()); 
     values.put(KEY_LAST_NAME, peepWithPic.getLast_name()); 
     values.put(KEY_PHONE_NUMBER_MOBILE, peepWithPic.getPhone_mobile()); 
     values.put(KEY_PHONE_NUMBER_OFFICE, peepWithPic.getPhone_office()); 
     values.put(KEY_HAS_DIRECT_REPORTS, peepWithPic.getHas_direct_reports()); 
     values.put(KEY_EMAIL, peepWithPic.getEmail()); 
     values.put(KEY_COST_CENTER, peepWithPic.getCost_center_id()); 

     return database.update(TABLE_CONTACTS, values, KEY_ID + " = ?", 
       new String[] {String.valueOf(peepWithPic.getEmployee_number())}); 
    } 

    //Delete single contact 
    public void deletedContact(PeepWithPic peepWithPic) { 
     SQLiteDatabase database = this.getWritableDatabase(); 
     database.delete(TABLE_CONTACTS, KEY_ID + " = ?", 
       new String[] {String.valueOf(peepWithPic.getEmployee_number())}); 
     database.close(); 
    } 
} 

MainActivity;我收到一个错误,说错误:(59,47)错误:不兼容的类型:ArrayList不能转换为Contex。不知道这甚至意味着什么。我只是试图将OkHttp3调用的响应保存到数据库,以便我可以使用数据库显示信息或进行另一次调用,以便在需要时获取更多数据,因为此Web服务非常慢。

我将此添加到构造函数中。我知道得到错误:(59,72)错误:不兼容的类型:ArrayList不能转换为PeepWithPic。由于我需要传递模型以保存到localDB,但我需要它作为ArrayList以在ListView适配器中显示它,所以对于如何传递此信息感到困惑。

databaseHandler = new DatabaseHandler(getApplicationContext(), mPeepWithPics); //this is in MainActivity 

private final PeepWithPic peepWithPic; 
public DatabaseHandler(Context context, PeepWithPic peepWithPic) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
     this.peepWithPic = peepWithPic; 
    } 
+0

你的问题有点模糊,或者至少非常宽泛。你坚持什么部分?你看到错误吗? – nasch

+0

我在底部更新了我的问题。谢谢你指出它不是很清楚。 –

回答

0

I am getting an error that says Error:(59, 47) error: incompatible types: ArrayList cannot be converted to Contex. Not sure what that even means.

您应该考虑做一些基本的Java培训,使你能够理解你的IDE是给你的消息。这是告诉你,构造函数期待Context,并且你正试图通过ArrayList。您需要传入一个Context,可能是MainActivity实例(this)。

+0

我已将getApplicationContext传递给databaseHandler,我可以运行该应用程序。我想要做的是将来自Web服务调用的响应添加到数据库,但不知道如何做到这一点。我读过的大多数指南都将一系列信息硬编码到数据库中。我有treid databaseHandler.addContact(mPeepWithPics),但我知道这是行不通的,因为它想要的模型,我想通过它ArrayList –

+0

我不确定你的问题到底在哪里。您知道如何获取项目列表到数据库中?那么,将服务器响应转换为对象列表的问题呢? – nasch

+0

我有一个传递peepWithPics到databaseHandler的问题。即使当我在onResponse中解析响应并尝试将其传递给databasehandler.addContact时,我遇到了错误,我无法获取ArrayList并将其转换为Model类。我明白为什么,但不知道如何将解析的ArrayList onResponse()传递给数据库。 –

0

DatabaseHandler构造函数参数是上下文,但是您注入了ur模型。

改变这一点:

public DatabaseHandler(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

public DatabaseHandler(Context context, Mymodel model) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
     this.model = model; 
    } 
+0

更新了代码的结尾,我对该错误感到困惑。我需要传递模型以保存到LocalDB,但需要将其作为ArrayList填充适配器以供listview使用。 –