주니어개발자_ฅʕ•̫͡•ʔฅ

Android 앱 런처 만들기3 (sqlite이용, 내부저장소에 앱 정보 저장) 본문

AndroidStudio

Android 앱 런처 만들기3 (sqlite이용, 내부저장소에 앱 정보 저장)

뚜비뚜밥_98 2021. 10. 11. 22:34

오늘은 저번에 만들었던 런처 앱에서 앱을 추가한 뒤

스마트폰의 전원을 껐다가 켜도

그  정보가 유지될 수 있도록

앱 이름과 앱 위치명, 앱 로고를

내부 저장소에 저장하려고 한다

 

내부 저장소란

앱 내의 저장소를 이용하는거라

앱을 삭제하면 내부저장소에 저장한 데이터가 함께 삭제된다.

 

시작하기 전에 앱 런처를 처음 만든다면

밑에 첨부된 순서대로 먼저 구현하길 바람

https://toubi-tobap.tistory.com/12

 

Android app을 앱 런처로 만들기 (홈 만들기)

태블릿이나 핸드폰을 켰을때 직접 만든 앱이 홈화면으로 지정되어 켜졌으면 해서 알아봤다. 먼저 앱 런처를 만들기 위해서 참고한 사이트 https://beomseok95.tistory.com/134 안드로이드 앱런처 만들기

toubi-tobap.tistory.com

https://toubi-tobap.tistory.com/13

 

Android 앱 런처 만들기2 (홈 만들기, 앱 추가하기)

홈 앱에 내가 원하는 앱을 선택하여 추가하고자 한다. ↓↓내가 참고한 사이트↓↓ https://code.tutsplus.com/tutorials/build-a-custom-launcher-on-android--cms-21358 Build a Custom Launcher on Android Int..

toubi-tobap.tistory.com

위의 과정이 다 끝났다면

프로젝트에 DataBase클래스를 하나 생성한다.

클래스명은 각자 편한대로 작성

본인은 Database로 지정했다.

 

 

Database.class

Database클래스에 SQLiteOpenHelper를 extends

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class Database extends SQLiteOpenHelper {

    public Database(Context context) {
        super(context, "Menu", null, 2); //테이블 명 : Menu
    }

    //DB 처음 만들때 호출. - 테이블 생성 등의 초기 처리.
    @Override
    public void onCreate(SQLiteDatabase db) {
    	/**
        * id = 칸번호, label = 앱명, name = 앱주소, image = 앱이미지
        * 모두 문자형태
        **/
        db.execSQL("CREATE TABLE Menu (id TEXT, name TEXT, addr TEXT, image TEXT);");
        //result.append("\nt3 테이블 생성 완료.");
    }

    //DB 업그레이드 필요 시 호출. (version값에 따라 반응)
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS Menu");
        onCreate(db);
    }
}

 

MainActivity로 돌아와서

Database.class와 SQLiteDatabase의 객체 선언

private static Database dbHelper;

private SQLiteDatabase db;

 

앱명, 주소, 이미지 등의 정보를 저장할ArrayList 객체 선언

private ArrayList<HashMap<String, String>> personList;

 

위에서 선언한 Database 객체와 ArrayList를 onCreate에서 생성

dbHelper = new Database(this);

personList = new ArrayList<HashMap<String, String>>();

 

그리고 앱 정보를 저장하는 메소드를 작성해주는데

메소드명은 각자 편한대로 작성

본인은 저번에 홈 앱 만들기2 에서 사용했던 메소드에 추가로 작성했다.

 

MainActivity의 addApp() 메소드

    private void addApp(Bitmap bitmap, ImageButton btn, TextView textView, int indexNum, String label, String name) {
        btn.setImageBitmap(bitmap);
        textView.setText(label);
        names.add(indexNum, name);

        String sql = "";

        /**
         * id -> label -> name -> image 순
         *칸번호  앱명   앱주소명   이미지값
         * **/
        String id = Integer.toString(indexNum + 1);
        String appLabel = label;
        String appName = name;
        
        /** bitmap to String, 비트맵을 문자열로 변환 **/
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 70, baos);
        byte[] bytes = baos.toByteArray();

        String appImage = Base64.encodeToString(bytes, Base64.DEFAULT);
        //db생성
        db = dbHelper.getWritableDatabase();
        //데이터 저장할 sql문 작성
        sql = String.format("INSERT INTO Menu VALUES('" + id + "','" + appLabel + "','" + appName + "','" + appImage + "');");
        //sql문 전달
        db.execSQL(sql);
    }

 

이제 앱을 껐다가 켰을때

저장된 앱 정보를 가져오는 메소드를 작성

 

MainActivity에 getData() 메소드 작성

private void getData(){

        db = dbHelper.getWritableDatabase();

        try {
            //SELECT문을 사용하여 테이블에 있는 데이터를 가져옴
            Cursor c = db.rawQuery("SELECT * FROM Menu;", null);
            if (c != null) {
                if (c.moveToFirst()) {
                    do {
                        String id = c.getString(0);
                        String label = c.getString(1);
                        String name = c.getString(2);
                        String image = c.getString(3);
                        
                        //HashMap에 넣기
                        HashMap<String, String> persons = new HashMap<String, String>();

                        persons.put("id", id);
                        persons.put("label", label);
                        persons.put("name", name);
                        persons.put("image", image);
                        //ArrayList에 추가
                        personList.add(persons);

                    } while (c.moveToNext());

                    insertData();
                }
            }
            c.close();

        } catch (SQLiteException se) {
            Log.e("예외처리(오류)", se.getMessage());
        }
    }

 

MainActivity에 insertData() 메소드 작성

private void insertData() {
        Bitmap bitmap = null;
        String str = "";

        if (personList != null) {
        // personList = ArrayList
            for(HashMap<String, String> i : personList){

                str += i.get("id")+" , ";

                String label = i.get("label");
                String name = i.get("name");
                String id = i.get("id");

                try {
                    byte[] encodeByte = Base64.decode(i.get("image"), Base64.DEFAULT);
                    bitmap = BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
                } catch (Exception e) {
                    e.getMessage();
                }

                if(id.equals("1"))resetAppData(bitmap,btn1, btn1_label,0,label,name);
                // 2개 이상의 앱버튼을 만든다면 각 버튼에 따라 밑에와 같이 작성
                // if(id.equals("2"))resetAppData(bitmap,btn1, btn1_label,0,label,name);                   
            }
        }
    }

 

MainActivity에 resetAppData() 메소드 작성

 private void resetAppdata(Bitmap bitmap, ImageButton btn, TextView textView, int indexNum, String label, String name) {
        btn.setImageBitmap(bitmap);
        textView.setText(label);
        names.add(indexNum, name);
    }

 

그리고 앱이 끝날때 db 연결을 해제해야한다.

   @Override
    protected void onDestroy() {
        dbHelper.close();
        super.onDestroy();
    }

 

마지막으로 앱이 시작할때 바로 실행되는

onCreate메소드에서 getData()를 호출하면 된다.

 

전체 MainActivity 소스코드

public class MainActivity extends AppCompatActivity {

    private ImageButton btn1;
    private TextView btn1_label;

    private ArrayList<String> names = null;
    
    private static Database dbHelper;
    private ArrayList<HashMap<String, String>> personList;
    private SQLiteDatabase db;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        View decorView = getWindow().getDecorView();

        // 상태 표시줄을 숨김
        int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
        decorView.setSystemUiVisibility(uiOptions);   

        dbHelper = new Database(this);
        personList = new ArrayList<HashMap<String, String>>();
        
        names = new ArrayList<>();
        for (int i = 0; i < 6; i++) {
            names.add(i, "");
        }
        
        btn1 = (ImageButton) findViewById(R.id.image_btn_1);
        btn1_label = (TextView) findViewById(R.id.btn1_label);

        btn1.setOnClickListener(view -> {
        Intent intent = new Intent(this, AppsListActivity.class);
          startApp(btn1_label.getText().toString(), intent, 1);
        });

    }
    
     @Override
    protected void onStart(){
        super.onStart();

        dbHelper = new Database(this);
        personList = new ArrayList<HashMap<String, String>>();
        getData();
    }
    
     @Override
    protected void onDestroy() {
        dbHelper.close();
        super.onDestroy();
    }
    
    public void startApp(String textView, Intent intent, int num) {
        PackageManager manager = this.getPackageManager();

		// 이미지 버튼에 선택된 앱이 없다면 앱 리스트 보이기
        if (textView == "") startActivityForResult(intent, num);
        // 이미지 버튼에 선택된 앱이 있다면 앱 실행
        else {
            Intent activity = manager.getLaunchIntentForPackage(names.get(num - 1).toString());
            activity.addCategory(Intent.CATEGORY_LAUNCHER);
            startActivity(activity);
        }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {

            Toast.makeText(getApplicationContext(), "앱이름 : " + data.getStringExtra("label") +
                    "\n앱주소 : " + data.getStringExtra("name"), Toast.LENGTH_SHORT).show();

            byte[] arr = data.getByteArrayExtra("icon");
            Bitmap bitmap = BitmapFactory.decodeByteArray(arr, 0, arr.length);

            // requestCode == 1로 호출한 경우에만 처리
            // 위에서 startActivityForResult(intent,1); >> 이부분
           
            if (requestCode == 1) {
            
            // data.getStringExtra("label") 이부분은
            // AppsListActivity에서 label이란 이름으로 보낸 String 값(앱 이름)을 가져오는 것이다.
            // data.getStringExtra("name") 이부분은 name이라는 이름으로 String 값 보냄(앱 주소)
            
                addApp(bitmap, btn1, btn1_label, 0,
                        data.getStringExtra("label"), data.getStringExtra("name"));
            } 
            
            
// 			  버튼을 여러개로 해놓고 사용한다면
// 			  밑에 주석 친 부분 처럼 추가해서 사용하면 된다.
           
//            if (requestCode == 2) {
//                addApp(bitmap, btn2, btn2_label, 1,
//                        data.getStringExtra("label"), data.getStringExtra("name"));
//            } 

        }
    }

    private void addApp(Bitmap bitmap, ImageButton btn, TextView textView, int indexNum, String label, String name) {
        btn.setImageBitmap(bitmap);
        textView.setText(label);
        names.add(indexNum, name);

        String sql = "";

        /**
         * id -> label -> name -> image 순
         *칸번호  앱명   앱주소명   이미지값
         * **/
        String id = Integer.toString(indexNum + 1);
        String appLabel = label;
        String appName = name;
        
        /** bitmap to String, 비트맵을 문자열로 변환 **/
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 70, baos);
        byte[] bytes = baos.toByteArray();

        String appImage = Base64.encodeToString(bytes, Base64.DEFAULT);
        //db생성
        db = dbHelper.getWritableDatabase();
        //데이터 저장할 sql문 작성
        sql = String.format("INSERT INTO Menu VALUES('" + id + "','" + appLabel + "','" + appName + "','" + appImage + "');");
        //sql문 전달
        db.execSQL(sql);
    }
    
    private void getData(){

        db = dbHelper.getWritableDatabase();

        try {
            //SELECT문을 사용하여 테이블에 있는 데이터를 가져옴
            Cursor c = db.rawQuery("SELECT * FROM Menu;", null);
            if (c != null) {
                if (c.moveToFirst()) {
                    do {
                        String id = c.getString(0);
                        String label = c.getString(1);
                        String name = c.getString(2);
                        String image = c.getString(3);
                        
                        //HashMap에 넣기
                        HashMap<String, String> persons = new HashMap<String, String>();

                        persons.put("id", id);
                        persons.put("label", label);
                        persons.put("name", name);
                        persons.put("image", image);
                        //ArrayList에 추가
                        personList.add(persons);

                    } while (c.moveToNext());

                    insertData();
                }
            }
            c.close();

        } catch (SQLiteException se) {
            Log.e("예외처리(오류)", se.getMessage());
        }
    }
    
    private void insertData() {
        Bitmap bitmap = null;
        String str = "";

        if (personList != null) {
        // personList = ArrayList
            for(HashMap<String, String> i : personList){

                str += i.get("id")+" , ";

                String label = i.get("label");
                String name = i.get("name");
                String id = i.get("id");

                try {
                    byte[] encodeByte = Base64.decode(i.get("image"), Base64.DEFAULT);
                    bitmap = BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
                } catch (Exception e) {
                    e.getMessage();
                }

                if(id.equals("1"))resetAppData(bitmap,btn1, btn1_label,0,label,name);
                // 2개 이상의 앱버튼을 만든다면 각 버튼에 따라 밑에와 같이 작성
                // if(id.equals("2"))resetAppData(bitmap,btn1, btn1_label,0,label,name);                   
            }
        }
    }
    
     private void resetAppdata(Bitmap bitmap, ImageButton btn, TextView textView, int indexNum, String label, String name) {
        btn.setImageBitmap(bitmap);
        textView.setText(label);
        names.add(indexNum, name);
    }

}

 

중간에 객체 이름을 수정하였기에

혹시 오류가 뜨거나할 수 있다

 

오류가 뜬다면 알려주시길 바랍니다.