2017-01-13 18 views
0

Я разбираю ответ веб-службы с помощью XMLPullParser и хотел бы сохранить это в локальной базе данных, чтобы иметь возможность уменьшить объем сетевого трафика, поскольку API не является наиболее эффективным для мобильный.Не удалось сохранить XML-синтаксический ответ на базу данных

Я создал класс базы данных и не знаю, как разместить ответ в базе данных, а затем использовать его для получения моей информации. Мне нужно заполнить список или снова обратиться за помощью, чтобы получить больше данных, если это необходимо, потому что база данных не работает, это есть.

Мои 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, который имеет сетевой вызов и 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 = новый DatabaseHandler (mPeepWithPics); Я получаю сообщение об ошибке Error: (59, 47) error: несовместимые типы: ArrayList не может быть преобразован в Contex. Не уверен, что это значит. Я просто пытаюсь сохранить ответ от вызова OkHttp3 в базу данных, чтобы я мог использовать базу данных для отображения информации или сделать другой звонок, чтобы получить больше данных, когда это необходимо, поскольку этот веб-сервис выполняется очень медленно.

Я добавил это к конструктору. Я знаю, что get Error: (59, 72) error: несовместимые типы: 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 в базу данныхHandler, и я могу запустить приложение. То, что я пытаюсь сделать, это добавить ответ от вызова веб-службы в базу данных, но не уверен, как это сделать. Большинство руководств, которые я прочитал, жестко кодируют список информации в свою базу данных. У меня есть treid databaseHandler.addContact (mPeepWithPics), но я знаю, что это не работает, поскольку он хочет Model, и я пытаюсь передать ему ArrayList –

+0

Я не уверен, где именно ваша проблема. Вы знаете, как получить список элементов в базе данных? Так возникает проблема с преобразованием ответа сервера в список объектов? – nasch

+0

У меня проблема с передачей peepWithPics в базу данныхHandler.Даже когда я принимаю разобранный ответ в onResponse и пытаюсь передать его команде databasehandler.addContact, я получаю сообщение об ошибке, когда я не могу взять ArrayList и преобразовать его в класс Model. Я понимаю, почему, но не уверен, как передать проанализированный ArrayList в onResponse() в базу данных. –

0

DatabaseHandler - это контекст, но вы вводите модель ур.

изменить это:

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 для заполнения адаптера для списка. –