2026/03/25

오늘의 이야기

https://developer.android.com/studio/preview/studio-bot/availability

Studio Bot Availability  |  Android Studio  |  Android Developers

Studio Bot is available in over 140 countries and territories.

developer.android.com


android studio 에도 bot이 적용 될 수 있다네요.
아직은 canary 버전이라 안정감은 덜 하지만  금새 stable 해 질 것이라 믿으며 도전해 보겠습니다.

아직은 영어로만 대화가 가능 하다네요. ㅠㅠ
얼른 한글을 알게 되길 바라며... studio bot 이야기를 옮겨 봅니다.


개발자페이지






오늘의 이야기

오늘도 좋은 생각을 가지고 긍정적인 에너지를 느끼세요! 😊 좋은 생각은 기분을 좋게 만들고, 인생을 긍정적으로 바라보게 도와줍니다. 다음과 같은 좋은 생각을 해보세요:

오늘은 무엇이든 성취할 수 있는 날이다.
나는 주변 사람들에게 긍정적인 영향을 줄 수 있다.
나는 나의 목표를 향해 꾸준히 발전하고 있다.
나는 어려움을 극복할 수 있는 내면의 힘이 있다.
나는 항상 배우고 성장하는 중이다.

이러한 긍정적인 생각을 마음속에 간직하고, 오늘 하루도 행복하고 활기찬 하루 되시길 바랍니다!

인생을 긍정적으로 바라보는 것은 쉽지 않을 수 있지만, 몇 가지 팁을 통해 긍정적인 마음가짐을 기르는 데 도움이 될 수 있습니다.

감사의 마음을 키우기: 일상에서 좋은 일과 소중한 사람들에게 감사의 마음을 표현하며 긍정적인 에너지를 느끼세요.
목표 설정: 목표를 세우고 그것을 달성하기 위해 노력함으로써 성취감을 느끼고 긍정적인 마음을 유지할 수 있습니다.
자기 칭찬하기: 자신의 능력과 성취를 인정하고 칭찬함으로써 자신감을 키우고 긍정적인 마음을 갖게 됩니다.
건강한 생활습관: 규칙적인 운동, 올바른 식습관, 충분한 수면 등 건강한 생활습관을 유지하면 기분이 좋아지고 긍정적인 마음을 느낄 수 있습니다.
스트레스 관리: 스트레스를 줄이기 위해 명상, 호흡법, 요가 등의 기법을 사용하거나 취미 활동을 즐기세요.
긍정적인 사람들과 함께하기: 긍정적인 사람들과 어울리면 그들의 긍정 에너지가 전해져 올바른 마음가짐을 유지하는 데 도움이 됩니다.
긍정적인 생각 연습하기: 부정적인 생각을 긍정적인 것으로 바꾸려고 노력하며, 시간이 지남에 따라 긍정적인 사고방식이 습관이 됩니다.

이러한 팁들을 차근차근 실천해보면 인생을 긍정적으로 바라보는 데 도움이 될 것입니다. 기억하세요, 변화는 하루아침에 이루어지지 않습니다. 꾸준한 노력과 시간이 필요하니 인내심을 가지고 연습해보세요.





오늘의 이야기



#스치니1000프로젝트 #재미 #행운기원 #Compose #Firebase

🎯 야 너 토요일마다 로또 확인하냐?
나도 맨날 "혹시나~" 하면서 봤거든 ㅋㅋ

근데 이제는 그냥 안 해
AI한테 맡겼어 🤖✨

그것도 구글 Gemini로다가!

그래서 앱 하나 만들었지
👉 "로또 예상번호 by Gemini" 🎱

AI가 분석해서 번호 딱! 뽑아줌
그냥 보고 참고만 하면 됨

재미로 해도 좋고…
혹시 모르는 거잖아? 😏


https://play.google.com/store/apps/details?id=com.billcorea.gptlotto1127




오늘의 이야기

안드로이드 레이아웃은 XML 파일을 사용하여 정의하는 것이 일반적입니다. 최근에는 Jetpack Compose라는 새로운 레이아웃 라이브러리가 도입되어 XML 레이아웃과 함께 사용되고 있습니다.


XML 레이아웃의 장점



  • 익숙한 방식: XML은 개발자들이 익숙한 레이아웃 방식입니다.

  • 다양한 레이아웃 지원: XML은 다양한 종류의 레이아웃을 지원합니다.

  • 성숙한 생태계: XML 레이아웃은 오랜 시간 동안 사용되어 왔기 때문에 다양한 라이브러리와 툴이 지원됩니다.


XML 레이아웃의 단점



  • 복잡한 코드: XML 레이아웃은 복잡한 UI를 구현하기 위해 많은 코드를 작성해야 합니다.

  • 유지보수 어려움: XML 레이아웃은 유지보수가 어렵습니다.

  • 성능 저하: XML 레이아웃은 Jetpack Compose에 비해 성능이 저하될 수 있습니다.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="안녕하세요!" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="확인" />

</LinearLayout>

Jetpack Compose의 장점



  • 간결한 코드: Jetpack Compose는 declarative programming을 사용하여 간결한 코드로 UI를 구현할 수 있습니다.

  • 유지보수 용이성: Jetpack Compose는 유지보수가 쉽습니다.

  • 성능 향상: Jetpack Compose는 XML 레이아웃에 비해 성능이 향상될 수 있습니다.

  • 새로운 기능 지원: Jetpack Compose는 새로운 기능을 지속적으로 추가하고 있습니다.


Jetpack Compose의 단점



  • 새로운 기술: Jetpack Compose는 아직 새로운 기술이기 때문에 개발자들이 익숙하지 않을 수 있습니다.

  • 지원 부족: Jetpack Compose는 아직 지원이 부족한 부분이 있습니다.

  • 호환성 문제: Jetpack Compose는 아직 모든 Android 기기에서 완벽하게 호환되지 않을 수 있습니다.


@Composable
fun MyLayout() {
// 레이아웃의 기본 컨테이너를 생성합니다.
Box(modifier = Modifier.fillMaxSize()) {
// TextView를 생성합니다.
Text(text = "안녕하세요!")

// Button을 생성합니다.
Button(onClick = { /* 버튼을 클릭하면 실행할 작업 */ }) {
Text(text = "확인")
}
}
}

 


결론


XML 레이아웃은 안정적이고 다양한 레이아웃을 지원하는 장점이 있습니다. Jetpack Compose는 간결한 코드, 유지보수 용이성, 성능 향상 등의 장점이 있습니다.


XML 레이아웃의 장점 10가지



  1. 익숙한 방식

  2. 다양한 레이아웃 지원

  3. 성숙한 생태계

  4. 코드 재사용성

  5. 유연성

  6. 테스트 용이성

  7. 디버깅 용이성

  8. 컴파일 시간 최적화

  9. 배포의 간편함

  10. 비용 절감


Jetpack Compose의 장점 10가지



  1. 간결한 코드

  2. 유지보수 용이성

  3. 성능 향상

  4. 새로운 기능 지원

  5. 코드 재사용성

  6. 유연성

  7. 테스트 용이성

  8. 디버깅 용이성

  9. 컴파일 시간 최적화

  10. 배포의 간편함


최종 선택


어떤 레이아웃 방식을 선택할지는 프로젝트의 요구 사항과 개발자의 선호도에 따라 다릅니다.



  • 익숙한 방식과 안정성을 원하는 경우: XML 레이아웃을 선택하는 것이 좋습니다.

  • 새로운 기술과 성능 향상을 원하는 경우: Jetpack Compose를 선택하는 것이 좋습니다.


개인적인 의견


저는 XML 레이아웃과 Jetpack Compose를 모두 사용해 보았습니다. 개인적으로는 Jetpack Compose가 더 매력적인 것 같습니다. 간결한 코드와 유지보수 용이성, 성능 향상 등의 장점이 마음에 듭니다. 하지만 아직 새로운 기술이기 때문에 완전히 익숙하지는 않습니다.


앞으로 Jetpack Compose가 더욱 발전하여 XML 레이아웃의 단점을 모두 극복할 수 있기를 기대합니다.


 


jetpack compose layout&nbsp; 예제



 





오늘의 이야기


#스하리1000명프로젝트

스치니들!
내가 만든 이 앱은, 내 폰에 오는 알림 중에서 중요한 키워드가 있는 경우
등록해둔 친구에게 자동으로 전달해주는 앱이야 📲

예를 들어, 카드 결제 알림을 와이프나 자녀에게 보내주거나
이번 달 지출을 달력처럼 확인할 수도 있어!

앱을 함께 쓰려면 친구도 설치 & 로그인해줘야 해.
그래야 친구 목록에서 서로 선택할 수 있으니까~
서로 써보고 불편한 점 있으면 알려줘 🙏

👉 https://play.google.com/store/apps/details?id=com.nari.notify2kakao





오늘의 이야기

gpt 와 대화를 시작해 보기



오랜만에 xml Layout 버전으로 앱을 구현해 보았습니다. 요새는 jetpack compose 만으로 layout 을 구성해 왔기 때문에... 이제 와서? 다시 xml 버전으로 layout 을 만들어 봅니다.  


 


다시 한번 느끼는 것이지만, 번거롭기는 합니다.  그래서 chatGPT 에게 질문을 해 보았습니다. 


 


do you know android recyclerview ?

 


문법에 맞는 질문은 아닐 겁니다.  그래도 친절하게 답을 해 줍니다. 


 


Yes, I'm familiar with Android RecyclerView. RecyclerView is a powerful and flexible Android UI component that is used to display a scrollable list of items efficiently. It's commonly used to implement lists, grids, and other types of scrollable views in Android apps.


Here are some key points about RecyclerView:



  1. Efficiency: RecyclerView is designed to be more efficient than its predecessor, ListView. It recycles item views that are no longer visible on the screen, which reduces memory consumption and improves performance.

  2. Adapter: You need to create an adapter that extends the RecyclerView.Adapter class. This adapter is responsible for creating and binding views for the data items you want to display in the RecyclerView.

  3. LayoutManager: RecyclerView uses a LayoutManager to position and arrange the items on the screen. Android provides several built-in LayoutManagers like LinearLayoutManager, GridLayoutManager, and StaggeredGridLayoutManager to control the layout of items.

  4. Item Decoration: You can customize the appearance of items and their dividers by using item decorators.

  5. Item Animations: RecyclerView supports item animations out of the box, making it easy to add animations when items are inserted, removed, or changed.

  6. Click Handling: You can set click listeners on individual items in the RecyclerView to handle user interactions.

  7. Data Updates: When the underlying data changes, you can notify the RecyclerView and its adapter to update the view accordingly using methods like notifyDataSetChanged(), notifyItemInserted(), notifyItemRemoved(), etc.

  8. Pagination: RecyclerView can be used for implementing endless scrolling or pagination where more data is loaded as the user scrolls to the end of the list.

  9. Item Decorations: You can customize the appearance of items and their dividers by using item decorations.

  10. ItemTouchHelper: This utility class allows you to implement swipe-to-dismiss and drag-and-drop functionality in a RecyclerView.


RecyclerView is a versatile component that's widely used in Android app development for creating complex lists and grids with various layouts and interactive features. It offers a more flexible and efficient way to handle dynamic data than its predecessors like ListView.


 


친철하기도 합니다.  그래서 이번에는 다짜고짜 다음과 같이 질문을 했습니다.


 


how to add button onclick?

버튼을 하나 달고 싶다고 했습니다. 


 


To add a button with an OnClickListener (a click event) in an Android RecyclerView, you can follow these steps:



  1. Create your RecyclerView layout: You should have a layout XML file that defines the appearance of each item in the RecyclerView. This layout should include the Button view that you want to click. For example:


<!-- item_layout.xml -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Item Text" />

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me" />

</LinearLayout>

 



  1. Create a ViewHolder: In your RecyclerView adapter, create a ViewHolder class that will hold references to the views in your item layout. Initialize and set the OnClickListener for the Button in the ViewHolder constructor.


public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

private List<String> itemList;

// Constructor and other methods go here...

public static class MyViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public Button button;

public MyViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textView);
button = itemView.findViewById(R.id.button);

// Set an OnClickListener for the Button
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Handle button click here
int position = getAdapterPosition(); // Get the item position
if (position != RecyclerView.NO_POSITION) {
// Perform some action based on the item position
// For example, you can display a toast message
String itemText = itemList.get(position);
Toast.makeText(itemView.getContext(), "Button clicked for: " + itemText, Toast.LENGTH_SHORT).show();
}
}
});
}
}

// More adapter methods go here...
}

 



  1. Set the Adapter: In your activity or fragment where you have the RecyclerView, set the adapter for the RecyclerView and provide the data.


RecyclerView recyclerView = findViewById(R.id.recyclerView);
MyAdapter adapter = new MyAdapter(itemList); // itemList is your data source
recyclerView.setAdapter(adapter);

Now, when you click the Button in any item of the RecyclerView, the OnClickListener you defined in the ViewHolder will be triggered, and you can perform the desired action, such as displaying a toast message or navigating to another screen.


Remember to replace itemList with your actual data source, and make sure to adapt the code to your specific requirements.


 


주절주절 자세한 설명과 샘플 코드가 제시됩니다.


 


how to action in mainactivity for button click

그렇습니다. 저는 버튼을 클릭했을 때 처리 하는 방법에 대해서 알고 싶었습니다.


 


To perform an action in the MainActivity when a button inside a RecyclerView item is clicked, you can follow these steps:


 


1. Set Up the RecyclerView and Adapter


In your MainActivity, you need to set up the RecyclerView and its adapter. This typically involves initializing the RecyclerView, setting its layout manager, and providing it with an adapter


RecyclerView recyclerView = findViewById(R.id.recyclerView);
MyAdapter adapter = new MyAdapter(itemList); // Replace MyAdapter with your adapter class and itemList with your data
recyclerView.setAdapter(adapter);

2.  Define an Interface:


Create an interface in your adapter class that will act as a callback mechanism to notify the MainActivity when a button is clicked. Define a method within this interface that the MainActivity will implement.


public interface OnItemClickListener {
void onButtonClick(int position);
}

3.  Implement the Interface:


In your adapter, maintain a reference to an instance of the OnItemClickListener interface.


private OnItemClickListener listener;

public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}

4. Call the Interface Method:


In the onClick listener for the Button in your ViewHolder, call the interface method to notify the MainActivity of the button click event.


button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
listener.onButtonClick(position);
}
}
}
});

5. Implement the Interface in MainActivity:


In your MainActivity, implement the OnItemClickListener interface and override the onButtonClick method to specify the action you want to perform when a button is clicked.


public class MainActivity extends AppCompatActivity implements MyAdapter.OnItemClickListener {

// ...

@Override
public void onButtonClick(int position) {
// Perform the action you want here based on the button click.
// You can access the position to identify the clicked item.
// For example:
String itemText = itemList.get(position);
Toast.makeText(this, "Button clicked for: " + itemText, Toast.LENGTH_SHORT).show();
}
}

6. Set the Listener in MainActivity


Finally, in your MainActivity, set the OnItemClickListener to your adapter instance to establish the connection between the MainActivity and the adapter.


adapter.setOnItemClickListener(this);

 

With these steps, when a button inside a RecyclerView item is clicked, the onButtonClick method in your MainActivity will be called, and you can perform the desired action based on the clicked item's position or any other relevant data.


 


이해가 되실까요?  친절 하게 단계별로 설명을 해 줍니다.


 


all code convert for kotlin

기본적으로 알려준 java code을 kotlin code로 변환해 달라고 해 봅니다.  물론 영어 문법에 맞는 질문은 아닐 듯합니다. 


 


Certainly! Here's the previous Java code converted to Kotlin for handling a button click in a RecyclerView:


// Step 1: Set up the RecyclerView and Adapter in MainActivity
val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
val adapter = MyAdapter(itemList) // Replace MyAdapter with your adapter class and itemList with your data
recyclerView.adapter = adapter

// Step 2: Define an Interface in your adapter
interface OnItemClickListener {
fun onButtonClick(position: Int)
}

// Step 3: Implement the Interface in your adapter
class MyAdapter(private val itemList: List<String>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

private var listener: OnItemClickListener? = null

fun setOnItemClickListener(listener: OnItemClickListener) {
this.listener = listener
}

// ... onCreateViewHolder and other adapter methods ...

inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val textView: TextView = itemView.findViewById(R.id.textView)
val button: Button = itemView.findViewById(R.id.button)

init {
// Step 4: Call the Interface Method in the ViewHolder
button.setOnClickListener {
listener?.let {
val position = adapterPosition
if (position != RecyclerView.NO_POSITION) {
it.onButtonClick(position)
}
}
}
}
}
}

// Step 5: Implement the Interface in MainActivity
class MainActivity : AppCompatActivity(), MyAdapter.OnItemClickListener {

// ...

override fun onButtonClick(position: Int) {
// Step 6: Perform the action you want here based on the button click.
// You can access the position to identify the clicked item.
// For example:
val itemText = itemList[position]
Toast.makeText(this, "Button clicked for: $itemText", Toast.LENGTH_SHORT).show()
}
}

This Kotlin code follows the same structure and logic as the Java code but is written in Kotlin syntax. It should allow you to handle button clicks within a RecyclerView in a Kotlin-based Android app.


 


그래도 친절한 설명에 감사합니다.라고 해 주었습니다. ㅋㅋ~


고맙다 했더니...



recycleview button don't click

그런데 제시된 코드를 활용해서 구현해 보아도 버튼을 추가했을 때 버튼 클릭에 대한 처리가 잘 되지 않는 것을 알게 되었습니다.  그래서 버튼 이벤트에 대한 의문을 말해 보았습니다.


 


If the button inside your RecyclerView item is not responding to clicks, there could be a few reasons for this issue. Here are some common troubleshooting steps to resolve the problem:



  1. Check Layout XML: Ensure that the Button view in your RecyclerView item's layout XML has a valid android:id. The android:id is necessary for finding and interacting with the button programmatically.

  2. Check ViewHolder: Double-check your ViewHolder class to ensure that you are correctly initializing and setting the OnClickListener for the Button in the init block (in Kotlin) or the constructor (in Java) of your ViewHolder.

  3. Verify Adapter Configuration: Make sure that you set the adapter for your RecyclerView correctly in your MainActivity. The code should look like this in Kotlin:


val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
val adapter = MyAdapter(itemList)
recyclerView.adapter = adapter

Ensure that you also set the OnItemClickListener in your MainActivity:


adapter.setOnItemClickListener(this)


  1. Check Item Data: Ensure that your itemList contains valid data that matches the number of items you expect to see in the RecyclerView. If your data is empty or contains fewer items than expected, it might give the impression that buttons are not clickable.

  2. Avoid Nested RecyclerViews: If you have nested RecyclerViews (a RecyclerView inside another RecyclerView), make sure that you're handling click events correctly for both the outer and inner RecyclerViews.

  3. Check for Overlapping Views: Ensure that there are no other views overlapping the button that might prevent it from receiving touch events.

  4. Debugging: Use logging statements or a debugger to check if the OnClickListener for the Button is being set correctly and if the click event is reaching the onClick method.

  5. Button State: Verify that the Button is enabled and clickable. If the Button is programmatically disabled, it won't respond to clicks.

  6. Conflict with Parent Views: Ensure that there are no parent views of the RecyclerView or the Button that are consuming touch events or intercepting clicks.

  7. View Hierarchy: Check if the RecyclerView item layout hierarchy is complex or contains nested layouts. Sometimes, complex view hierarchies can affect touch event handling.


By carefully checking these points, you should be able to identify and resolve the issue with your RecyclerView's button not responding to clicks. If the problem persists, consider providing more details about your code and layout XML files so that I can offer more specific guidance.


 


친절하게 답을 해 주고 있습니다.


 


이제 구현을 해 볼 차례입니다.   ㅋ~  오늘은 chatGPT 와의 대화를 통해서 코드 구현 하는 이야기를 해 보았습니다.


 





오늘의 이야기

 


만원으로 즐기는 저녁식사



저녁 먹을 시간이 되었습니다. 오늘은 내 돈 내산 맛나고 간편한 저녁 먹은 이야기를 잠시 해 보겠습니다. 


 


 


https://place.map.kakao.com/1925920638



 


호스시


서울 영등포구 영등포로19길 15-1 1층 (당산동2가 146)


place.map.kakao.com




 


집 가는 길이 멀었습니다.   간편하게 저녁을 먹고 싶으나, 그것이 그렇게 쉽게 느껴지지는 않습니다. ㅋ~


이런저런 식당들이 뒤편으로 지나쳐 갑니다. 


 


오늘 저녁은 어떤것을 먹어야 맛나게 먹었다고 소문이 날까 하는 생각을 하며 길을 걷는 데,  횟집 하나가 눈에 들어옵니다.  저 집은 맛나게 먹을 수 있는 집인가 하는 궁금함을 가득 안고.


  


입장~


 


처음 가는 집은 항상 사장님께 여쭈어 봅니다. 어떤게 맛날까요?  그렇게 알려 주신 메뉴들 중에서 저렴하게 생긴 메뉴를 하나 주문 했습니다. 


 


1만 원으로 먹을 수 있는 정식입니다.  새우장 8마리 정도면 나름 괜찮은 식단이지 않을까 하는 생각입니다.


지금 가시면 드실 수 있을지는 모르겠습니다. ㅋ~


 



맛난 저녁 드세요.





오늘의 이야기


#스하리1000명프로젝트,
Parfois, il est difficile de parler avec des travailleurs étrangers, n'est-ce pas ?
J'ai créé une application simple qui aide ! Vous écrivez dans votre langue et les autres le voient dans la leur.
Il se traduit automatiquement en fonction des paramètres.
Super pratique pour des discussions faciles. Jetez-y un oeil quand vous en aurez l'occasion !
https://play.google.com/store/apps/details?id=com.billcoreatech.multichat416




오늘의 이야기

오늘은 구현하고자 하는 앱에서  MSSQL 등의 DB 서버 접속에 대한 이야기를 해 볼까 합니다. java에서 JDBC 등으로 DB Server 접속하는 web 서비스 구현을 해 보기는 했습니다만. android에서 jdbc 등으로 DB 접속을 구현해 보는 건 또 처음인 듯합니다. 


 


일반적으로 앱 서비스를 구현하더라도 DB 서버에 직접 접속하는 것은 그렇게 바람직한 모습은 아닌 것으로 생각이 듭니다.  그래도 한번 구현을 도전해 보겠습니다. 


 


    // MSSQL jdbc connect
implementation 'net.sourceforge.jtds:jtds:1.3.1'
// coroutines & lifecycle 처리를 위해서 2줄 추가
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2"

JDBC 을 접속하는 jtsd 라이브러리를 imlementation 했습니다. lifecycle 과 관련된 라이브러리는 안드로이드 앱이라는 제한성 때문에 비동기 처리를 해야 했기 때문에 추가했습니다. 


 


firebase 등의 API 가 지원되는 경우에는 API 가 비동기 통신을 지원하기 때문에 그냥 코드 작업을 진행할 수 있었지만, 이 프로젝트의 경우는 그 부분에 제한이 있었습니다. 


 


<uses-permission android:name="android.permission.INTERNET"/>

manifest 에 internet 사용을 위한 권한 허가를 설정했습니다.  우리가 사용하는 안드로이드 단말기는 WIFI 나  통신사의 통신망을 활용해서 외부와 통신을 해야 하기 때문에 기본적으로 넣어 두어야 합니다. 


 


이제 DB 와 통신을 하기 위한 Connecter을 구현해 보겠습니다. 


 


import android.os.StrictMode
import android.util.Log
import android.widget.EditText
import java.sql.Connection
import java.sql.DriverManager
import java.sql.SQLException

class MsConnection {

private val ip="서버IP:서버port"
private val db="database name"
private val username="username"
private val password="password"

fun dbConn():Connection? {
val policy=StrictMode.ThreadPolicy.Builder().permitAll().build()
StrictMode.setThreadPolicy(policy)
var conn:Connection?=null
var connString:String?=null
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver")
connString="jdbc:jtds:sqlserver://$ip;databaseName=$db;user=$username;password=$password"
conn=DriverManager.getConnection(connString)

} catch (ex:SQLException) {
Log.e("Error1 : ", "error ${ex.localizedMessage}")
} catch (ex1:ClassNotFoundException) {
Log.e("Error2 : ", "error ${ex1.localizedMessage}")
} catch (ex2:Exception) {
Log.e("Error3 : ", "error ${ex2.localizedMessage}")
}
return conn
}
}

mssql의 경우는 connection string을 jdbc:jtds:sqlserver... 이렇게 작성하는 것으로 확인이 되었습니다. oracle 이라면 jdbc:oracle:thin... 이런 식으로 작성을 하게 됩니다. 


 


다른 DB 서버와 접속을 하게 되더라도 비슷한 구조를 가지게 되지 않을 까 하는 생각이 듭니다. 


    fun doGetData() {
val dbConn = MsConnection().dbConn()
if (dbConn == null) {
Toast.makeText(context, context.getString(R.string.msgDontDBconn), Toast.LENGTH_SHORT).show()
return
}
viewModelScope.launch {
val sp = context.getSharedPreferences(context.packageName, Context.MODE_PRIVATE)
val userDiv = sp.getString("userdiv", "0")
val compDiv = sp.getString("comp_div", "")
val location = sp.getString("location", "")
var query = "select * from table_name where cnt > 0"
Log.e("", "query =$query")
val statement = dbConn.createStatement()
val rs = statement.executeQuery(query)
prods.clear()
while(rs.next()) {
val prodBean = Prod100Bean(
rs.getInt("seq"),
rs.getString("id"),
rs.getInt("cnt"),
)
Log.e("", "seq = ${prod100Bean.seq}")
prods.add(prod100Bean)
}
prods.sortByDescending { it.seq }
dbConn.close()
}
}

데이터를 읽어오는 코드는 이런 예제와 같이 구현이 될 수 있을 듯 합니다. 위 예제 코드는 viewModel에 들어 있는 fun 이기 때문에 viewModelScope.launch { }을 이용해서 thread 처리를 했습니다.  그렇게 비동기 처리를 하지 않는 경우 androi d는 오류를 표시하게 됩니다. 


 


이런 정도로 그 구현에 대해서 알아 보았습니다.   다음에도 이런 작업은 이제 수월하게 진행할 수 있을 것 같습니다. 


 


mssql 서버 접속 예시



 





오늘의 이야기


프로젝트를 위해 서울로 잠시 이전한 지도 벌써 3주가 넘었습니다.  주말에만 집에 다녀오니 주중에는 저녁 시간이 많이 한가로워 지기는 했습니다.  그렇다고 해서 운동을 찾아서 할 나는 아닌 것을 알기 때문에. 이렇게 글을 적어 보고 있습니다. 


 


서울에서의 일상은 20년 전 쯤 회사가 방배동에 있을 때였을 듯합니다. 그 이후로 수원에서 한 3년쯤 있었던 것 같고, 2006년 대전으로 이전한 이후에는 줄 곧 대전에서 생활을 했었습니다.  대전에서는 시간들은 출퇴근에 20분이 소요되지 않는 거리였고, 걸어서도 출퇴근이 가능한 곳이었기 때문에 한가롭게(?)  시간을 보냈다고 볼 수 있을 듯합니다. 


 


20여 년 만에 다시 서울에서의 시간들은 바글거리는 지하철에서부터 온몸으로 다가옵니다. 다들 바쁘게 같은 모습으로 출근을 하고 퇴근을 합니다. 


 


달라진 것이 있다면 그 때는 지하철에서 신문을 보는 사람이 많았는 데, 지금은 너나 할 것 없이 스마트폰을 쳐다봅니다. 아무리 콩나물시루 같은 칸에 있더라도 말입니다.  저는 조금 여유롭게 보이기 위해서 스마트폰으로 책을 듣고 있어서 손이 자유롭기는 합니다. 


 


임산부 보호석 ... 그때는 아마 없었던 것으로 기억합니다.  시대가 많이 변하기는 했습니다.  그래도 출산율은 최저라고 하기는 하지만 말입니다.  하루하루 지나가는 시간들이 다시금 새롭게 다가옵니다.  사실 어딘가에 소속되어 있다가 프리(Free)가 되고 나서는 길이라 더욱 그러할지도 모릅니다. 


 


프로젝트를 위해서 가는 그곳에도 아직 현직 있다는 여유로움(?)을 모른체 살아가는 사람들이 보입니다. 자신의 생각이 다 맞고 현재의 시간이 무한할 것 같은 생각을 하면서 말입니다.   다들 떠나는 그곳에서 무한할 듯 한 시간이 어느 순간 다 했음을 알게 되었을 때, 조금은 허전함이 덜 하기 위해서는 무언가 준비를 해야 할 것 같은 생각이 들어 뒤를 돌아본 시점에는 이미 난 그곳에 없다는 것을 알게 될 텐데 말입니다. 


 


아직 내가 숨어 있을 수 있는 우산(?) 아래에  있을 때, 미리 준비를 하시길 바랍니다. 뭐 그때는 모르고 시간이 지나가기는 하겠지만, 알게 되길 바라 봅니다. 


 


재미난 일들이 많아지기를 기도합니다.  오늘도 수고 하셨습니다.


 


지하철 이미지 ( 출처 : pixaboy )



 





오늘의 이야기


#billcorea #운동동아리관리앱
🏸 Schneedle, une application incontournable des clubs de badminton !
👉 Match Play – Enregistrez des scores et trouvez des adversaires 🎉
Parfait partout, seul, entre amis ou en club ! 🤝
Si vous aimez le badminton, essayez-le

Accédez à l'application 👉 https://play.google.com/store/apps/details?id=com.billcorea.matchplay




오늘의 이야기

https://developer.android.com/studio/preview/studio-bot/availability Studio Bot Availability  |  Android Studio  |  Android Developers Stud...