Почему база данных не вызывает onCreate в сервисе? - PullRequest
2 голосов
/ 03 марта 2020

Я новичок в xamarin и имею задачу создать своего рода персональный органайзер на Android. Главная особенность - создание заметок, задач, событий в различных действиях, а затем сохранение, удаление, редактирование и на разных экранах. По этой причине я использую SQLiteOpenHelper для создания базы данных в службе, чтобы иметь доступ к каждому действию, а затем вызываю методы из нее. Мой сервис гибридный, поэтому я связываюсь с каждым действием, пока оно работает. К сожалению, SQLiteOpenHelper.OnCreate не вызывает. Я зарегистрировал большинство возможных ошибочных частей, и это показало ошибку при создании БД. Вот мой код.

Services.cs

using Android.Util;
using Android.OS;
using Android.Content;
using Android.App;
using FinallyApp;
using Android.Database;
using OrgDatabase1;
using Android.Database.Sqlite;
using System;

namespace DatabaseService
{

    [Service(Name = "com.xamarin.DBservice")]
    public class DBConnectService : Service
    {
        DatabaseHelper DbHelper;
        SQLiteDatabase db;
        public IBinder Binder { get; private set; }

        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {

            Log.Debug("DemoService", "DemoService started");

            return StartCommandResult.NotSticky;
        }

        public override void OnCreate()
        {
            // This method is optional to implement

            base.OnCreate();
            DbHelper = new DatabaseHelper(this);
            Log.Debug("INSERVICE", "OncreateService");


            db = DbHelper.ReadableDatabase;
        }

        public override IBinder OnBind(Intent intent)
        {
            // This method must always be implemented
            Log.Debug("Service.OnBind", "OnBinded");
            this.Binder = new DBConnectBinder(this);
            return this.Binder;
        }

        public override bool OnUnbind(Intent intent)
        {
            // This method is optional to implement

            return base.OnUnbind(intent);
        }

        public override void OnDestroy()
        {
            // This method is optional to implement

            Binder = null;
            base.OnDestroy();
        }


        public ICursor GetTable(string table_name)
        {
            switch (table_name)
            {
                case DatabaseHelper.NOTE_TABLE:
                    string[] projection = { DatabaseHelper.COLUMN_NAME, DatabaseHelper.COLUMN_DESCRIPTION, DatabaseHelper.COLUMN_CREATION_DATE };
                    var cursor = db.Query(DatabaseHelper.NOTE_TABLE, projection, null, null, null, null, null);
                    return cursor;
                case DatabaseHelper.EVENT_TABLE:

                    return null;
                case DatabaseHelper.TODO_TABLE:

                    return null;
            }
            return null;
        }
        public ContentValues GetItem(string table_name, int position)
        {
            switch (table_name)
            {
                case DatabaseHelper.NOTE_TABLE:
                    string[] projection = { DatabaseHelper.COLUMN_NAME, DatabaseHelper.COLUMN_DESCRIPTION, DatabaseHelper.COLUMN_CREATION_DATE };
                    var cursor = db.Query(DatabaseHelper.NOTE_TABLE, projection, null, null, null, null, null);
                    cursor.MoveToPosition(position);
                    using (ContentValues item = new ContentValues())
                    {
                        item.Put(DatabaseHelper.COLUMN_NAME, cursor.GetString(cursor.GetColumnIndex(DatabaseHelper.COLUMN_NAME)));
                        item.Put(DatabaseHelper.COLUMN_DESCRIPTION, cursor.GetString(cursor.GetColumnIndex(DatabaseHelper.COLUMN_DESCRIPTION)));
                        item.Put(DatabaseHelper.COLUMN_CREATION_DATE, cursor.GetString(cursor.GetColumnIndex(DatabaseHelper.COLUMN_CREATION_DATE)));
                        item.Put(DatabaseHelper.COLUMN_ID, cursor.GetInt(cursor.GetColumnIndex(DatabaseHelper.COLUMN_ID)));
                        return item;
                    }
                case DatabaseHelper.EVENT_TABLE:

                    return null;
                case DatabaseHelper.TODO_TABLE:

                    return null;
            }
            return null;
        }
        public void InsertNote(string name, string description)
        {
            using (ContentValues contentV = new ContentValues())
            {
                contentV.Put(DatabaseHelper.COLUMN_NAME, name);
                contentV.Put(DatabaseHelper.COLUMN_DESCRIPTION, description);
                contentV.Put(DatabaseHelper.COLUMN_CREATION_DATE, DateTime.Now.ToString("g"));
                db.Insert(DatabaseHelper.COLUMN_NAME, null, contentV);
            }

        }
        public void DeleteItem(string table_name, int id)
        {
            db.Delete(table_name, DatabaseHelper.COLUMN_ID + "=" + id.ToString(), null);
        }
        public void UpdateItem(string table_name, int id, ContentValues values)
        {
            db.Update(table_name, values, DatabaseHelper.COLUMN_ID + "=" + id.ToString(), null);
        }
    }

    public class DBConnectBinder : Binder
    {
        public DBConnectBinder(DBConnectService service)
        {
            this.Service = service;
        }

        public DBConnectService Service { get; private set; }

        public ICursor GetTable(string table_name)
        {
            return Service.GetTable(table_name);
        }
        public ContentValues GetItem(string table_name, int position)
        {
            return Service.GetItem(table_name, position);
        }
        public void InsertNote(string name, string description)
        {
            Service.InsertNote(name, description);
        }
        public void DeleteItem(string table_name, int id)
        {
            Service.DeleteItem(table_name, id);
        }
        public void UpdateItem(string table_name, int id, ContentValues values)
        {
            Service.UpdateItem(table_name, id, values);
        }
    }

    public class DBConnectionServiceConnection : Java.Lang.Object, IServiceConnection
    {
        public DBConnectionServiceConnection(Activity activity)
        {
            IsConnected = false;
            Binder = null;
            this.activity = activity;
        }
        private Activity activity;
        public bool IsConnected { get; private set; }
        public DBConnectBinder Binder { get; private set; }

        public void OnServiceConnected(ComponentName name, IBinder service)
        {
            Binder = service as DBConnectBinder;
            IsConnected = this.Binder != null;
            Log.Debug("OnConnected", "Connected");
            if (IsConnected)
            {
                Log.Debug("IsConnected", "true");
                if (activity as MainActivity != null)
                {
                    MainActivity act = (MainActivity)activity;
                    act.GetDataFromService();
                }
                else if (activity as MainActivity != null)
                {
                    NoteItemPageActivity act = (NoteItemPageActivity)activity;
                    act.GetItemFromService();
                }
                else if (activity as CreationActivity != null)
                {
                    CreationActivity act = (CreationActivity)activity;
                    act.PrepareForCreate();
                }
            }
        }

        public void OnServiceDisconnected(ComponentName name)
        {
            IsConnected = false;
            Binder = null;

        }


    }
}

MainActivity.cs

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;
using Android.Support.V7.Widget;
using OrgDatabase1; 
using Android.Database;
using Android.Database.Sqlite;
using Toolbar = Android.Support.V7.Widget.Toolbar;
using DatabaseService;
using Android.Util;

namespace FinallyApp
{
    [Activity(MainLauncher = true)]
    public class MainActivity : AppCompatActivity, BottomNavigationView.IOnNavigationItemSelectedListener
    {
        TextView textMessage;
        BottomNavigationView navigation;

        ICursor cursor;
        RecyclerView mRecyclerView;
        RecyclerView.LayoutManager mLayoutManager;
        NoteAlbumAdapter mAdapter;
        Toolbar toolbar;

        DBConnectionServiceConnection Dbconnection;

        protected override void OnCreate(Bundle bundle)
        {

            base.OnCreate(bundle);
            Xamarin.Essentials.Platform.Init(this, bundle);
            SetContentView(Resource.Layout.activity_main);
            textMessage = FindViewById<TextView>(Resource.Id.message);
            navigation = FindViewById<BottomNavigationView>(Resource.Id.navigation);
            navigation.SetOnNavigationItemSelectedListener(this);
            mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
            mLayoutManager = new LinearLayoutManager(this);
            mRecyclerView.SetLayoutManager(mLayoutManager);
            StartService(new Intent(this, typeof(DBConnectService)));


            toolbar = FindViewById<Toolbar>(Resource.Id.toolbar);
            SetSupportActionBar(toolbar);
            toolbar.SetTitle(Resource.String.title_note);
        }
        protected override void OnStart()
        {
            base.OnStart();
            if (Dbconnection == null)
            {
                this.Dbconnection = new DBConnectionServiceConnection(this);
            }
            Intent serviceToStart = new Intent(this, typeof(DBConnectService));
            BindService(serviceToStart, this.Dbconnection, Bind.AutoCreate);

        }
        public void GetDataFromService()
        {
            Log.Debug("status", "InActivity");
            if (cursor == null)
            {
                Log.Debug("status", "ifCursorNull");
                cursor = Dbconnection.Binder.GetTable(DatabaseHelper.NOTE_TABLE);
                mAdapter = new NoteAlbumAdapter(cursor);
                mAdapter.ItemClick += OnNoteItemClick;
                mRecyclerView.SetAdapter(mAdapter);
            }
            else mAdapter.NotifyDataSetChanged();
        }
        protected override void OnResume()
        {
            base.OnResume();

        }
        void OnNoteItemClick(object sender, int position)
        {
            var intent = new Intent(this, typeof(NoteItemPageActivity));
            intent.PutExtra("position", position);
            StartActivity(intent);
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
        public bool OnNavigationItemSelected(IMenuItem item)
        {
            switch (item.ItemId)
            {
                case Resource.Id.navigation_note:
                    textMessage.SetText(Resource.String.title_note);
                    toolbar.SetTitle(Resource.String.title_note);
                    toolbar.SetBackgroundResource(Resource.Color.NoteMainColor);
                    return true;
                case Resource.Id.navigation_todo:
                    textMessage.SetText(Resource.String.title_todo);
                    toolbar.SetTitle(Resource.String.title_todo);
                    toolbar.SetBackgroundResource(Resource.Color.TodoMainColor);
                    return true;
                case Resource.Id.navigation_event:
                    textMessage.SetText(Resource.String.title_event);
                    toolbar.SetTitle(Resource.String.title_event);
                    toolbar.SetBackgroundResource(Resource.Color.EventMainColor);
                    return true;
            }
            return false;
        }
        protected override void OnSaveInstanceState(Bundle savedInstanceState)
        {

            base.OnSaveInstanceState(savedInstanceState);
        }
        protected override void OnRestoreInstanceState(Bundle savedInstanceState)
        {
            base.OnRestoreInstanceState(savedInstanceState);
            mAdapter.NotifyDataSetChanged();

        }
        public override bool OnCreateOptionsMenu(IMenu menu)
        {
            MenuInflater.Inflate(Resource.Menu.top_menus, menu);
            var delete_item = menu.FindItem(Resource.Id.menu_delete);
            delete_item.SetVisible(false);
            var edit_item = menu.FindItem(Resource.Id.menu_edit);
            edit_item.SetVisible(false);
            var save_item = menu.FindItem(Resource.Id.menu_save);
            save_item.SetVisible(false);
            var cancel_item = menu.FindItem(Resource.Id.menu_cancel);
            cancel_item.SetVisible(false);
            return base.OnCreateOptionsMenu(menu);
        }

        public override bool OnOptionsItemSelected(IMenuItem item)
        {
            switch (item.ItemId)
            {
                case Resource.Id.menu_create:
                    var current_section = navigation.SelectedItemId;
                    switch (current_section)
                    {
                        case Resource.Id.navigation_note:
                            var intent = new Intent(this, typeof(CreationActivity));
                            intent.PutExtra("CreationType", "Note");
                            StartActivity(intent);
                            return true;
                        case Resource.Id.navigation_todo:
                            var intent2 = new Intent(this, typeof(CreationActivity));
                            intent2.PutExtra("CreationType", "Todo");
                            StartActivity(intent2);
                            return true;
                        case Resource.Id.navigation_event:
                            var intent3 = new Intent(this, typeof(CreationActivity));
                            intent3.PutExtra("CreationType", "Event");
                            StartActivity(intent3);
                            return true;
                    }
                    return true;
            }
            return base.OnOptionsItemSelected(item);
        }
        protected override void OnStop()
        {
            UnbindService(Dbconnection);
            base.OnStop();
        }
        protected override void OnDestroy()
        {
            StopService(new Intent(this, typeof(DBConnectService)));
            base.OnDestroy();
        }
    }
}

SQLite.cs

using Mono.Data.Sqlite;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using System.IO;
using System.Data;
using Android.Database.Sqlite;
using Android.Database;
using Android.Content;
using Android.Util;

namespace OrgDatabase1
{
    public class DatabaseHelper : SQLiteOpenHelper
    {
        public const string NOTE_TABLE = "Notes";
        public const string EVENT_TABLE = "Events";
        public const string TODO_TABLE = "Todos";
        public const string COLUMN_ID = "_id";
        public const string COLUMN_NAME = "name";
        public const string COLUMN_CREATION_DATE = "creation_date";
        public const string COLUMN_DESCRIPTION = "description";
        public const string COLUMN_DEADLINE = "deadline";
        public static readonly string DbName = "database.db";
        public static readonly int DatabaseVersion = 1;
        public DatabaseHelper(Context context) : base(context, DbName, null, DatabaseVersion) { }
        public override void OnCreate(SQLiteDatabase db)
        {
            db.ExecSQL("CREATE TABLE [" + NOTE_TABLE + "] ([" + COLUMN_ID + "] INTEGER PRIMARY KEY AUTOINCREMENT, [" + COLUMN_NAME + "] TEXT NOT NULL, [" + COLUMN_DESCRIPTION + "] TEXT, [" + COLUMN_CREATION_DATE + "] TEXT NOT NULL);");
            Log.Debug("DATABASE","Access");

        }
        public override void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
        {

        }
    }
}

Спасибо.

Ответы [ 2 ]

0 голосов
/ 05 марта 2020

Спасибо, ребята, но я чувствую себя немного глупо, потому что я неправильно кодировал.

в db.Insert(DatabaseHelper.COLUMN_NAME, null, contentV); Я называю имя столбца вместо имени таблицы. Вот и все.

0 голосов
/ 04 марта 2020

SQLiteOpenHelper.OnCreate () будет выполняться только при первом создании базы данных. То есть, если приложение уже развернуто и запущено на вашем устройстве, этот метод больше не будет запускаться.

Сначала вы можете удалить приложение и повторно развернуть его на своем устройстве, а на этот раз - должен запускаться.

Чтобы удалить приложение, вы можете использовать adb:

adb uninstall your.package.name

Ссылаясь на предыдущее сообщение .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...