2026/02/24

오늘의 이야기


#스하리1000명프로젝트,
A veces es difícil hablar con trabajadores extranjeros, ¿verdad?
¡Hice una aplicación sencilla que ayuda! Escribes en tu idioma y los demás lo ven en el suyo.
Se traduce automáticamente según la configuración.
Súper útil para chatear fácilmente. ¡Echa un vistazo cuando tengas la oportunidad!
https://play.google.com/store/apps/details?id=com.billcoreatech.multichat416




오늘의 이야기

https://www.webcodegeeks.com/python/sort-numpy-arrays-in-python/



 


Sort NumPy arrays in Python - Web Code Geeks - 2022


Many of Python's popular libraries use NumPy under the hood as a fundamental pillar of their infrastructure. Beyond slicing, dicing, and manipulating


www.webcodegeeks.com




인터넷에 나와 있는 자료를 공유해 드립니다. 이글의 번역은 구글 번역기를 이용했습니다.


Python에서 NumPy 배열 정렬


많은 Python의 인기 있는 라이브러리는 NumPy 를 인프라의 기본 기둥으로 사용합니다. NumPy 라이브러리는 배열 슬라이싱, 다이싱 및 조작 외에도 배열의 요소를 정렬할 수 있는 다양한 기능을 제공합니다.
배열 정렬은 컴퓨터 과학의 많은 응용 프로그램에서 유용합니다.
데이터를 정렬된 형식으로 구성하고 요소를 빠르게 조회하며 공간 효율적인 방식으로 데이터를 저장할 수 있습니다.
패키지를 설치했으면 다음 명령을 실행하여 가져옵니다.


NumPy 정렬 알고리즘


numpy.sort() 함수를 사용하면 다양한 정렬 알고리즘을 사용하여 배열을 정렬할 수 있습니다. 'kind' 매개변수를 설정하여 사용할 알고리즘의 종류를 지정할 수 있습니다.
기본값은 '빠른 정렬'을 사용합니다. NumPy가 지원하는 다른 정렬 알고리즘에는 mergesort, heapsort, introsort 및 stable이 있습니다.
종류 매개변수를 'stable'로 설정하면 함수가 배열 데이터 유형을 기반으로 가장 안정적인 정렬 알고리즘을 자동으로 선택합니다.
일반적으로 'mergesort'와 'stable'은 데이터 유형에 따라 모두 timesort와 radixsort에 매핑됩니다.
정렬 알고리즘은 평균 실행 속도, 공간 복잡성 및 최악의 경우 성능으로 특징지을 수 있습니다.
또한 안정적인 정렬 알고리즘은 동일한 키를 가지고 있는 경우에도 항목을 상대적인 순서로 유지합니다. 다음은 NumPy 정렬 알고리즘의 속성에 대한 요약입니다.

...

기타의 내용은 인용된 본문을 참고하세요.... 이글의 번역은 구글 번역기를 이용했습니다.


Numpy 함수의 활용성에 대한 이해가 되는 하루였습니다.   작성자 분께 심심한 감사를 드립니다.





오늘의 이야기

오늘은 서핑을 하다 발견한 걸 옮겨 적어 본다. qrcode 스캔 하는 앱도 만들어 보았으니 qrcode 도 만들어 보는 거다.
https://diyver.tistory.com/170?category=980809







파이썬 QR코드 쉽게 생성하기


qrcode 모듈을 이용하여 파이썬으로 간단하게 QR코드를 생성할 수 있다. 1. qrcode 모듈 설치하기 아나콘다를 실행하고 아나콘다 명령 프롬프트를 켜서 아래 명령어를 입력한다. >>> pip install qrcode 2. Q


diyver.tistory.com




이 블로그에서 퍼 왔음을 밝힌다.

쉽기는 했다. 다면 import qrcode 을 했더니, install 해야 한다고 하는데, qrcode 로 설치된 것이 다른 버전이 있는 것 같은 생각이 든다. 설치하기 전에 잘 살펴보고 해야 할 것 같다.

qrcode 이미지



생성된 이미지 파일은 위와 같고. 하는 방법은 위의 블로그를 그대로 따라 했다. 단지, 내 컴퓨터에서는 qrcode 라이브러리 탐색에 문제가 있는 것 같다.

그래서 내가 아끼는 라즈베리파이 에서 설치하고 실행 했다. 하는 방법은 위 블로그에 나와 있고, 난 그저 옮겼을 뿐.


pip install qrcode
pip 설치 예시


소스 코드는 그대로


import qrcode url = "https://billcorea.tistory.com" qr_img = qrcode.make(url) qr_img.save('qr_url.png')

url 경로만 나의 것으로 변경 하기 생성된 이미지에 카메라로 찍어 보았더니, 그대로 나의 블로그의 url 이 보이고, 클릭하니 바로 넘어왔다. ㅋ~





오늘의 이야기


#billcorea #운동동아리관리앱
🏸 Schneedle, ¡una aplicación imprescindible para los clubes de bádminton!
👉 Match Play: registra puntuaciones y encuentra oponentes 🎉
¡Perfecto para cualquier lugar, solo, con amigos o en un club! 🤝
Si te gusta el bádminton, definitivamente pruébalo.

Ir a la aplicación 👉 https://play.google.com/store/apps/details?id=com.billcorea.matchplay




오늘의 이야기



 


앱을 만들다 보면, 간혹 지도에 현재 나의 위치를 표시해야 하는 경우가 생긴다. 그래서 간단하게 그 기능을 만들어 보도록 하겠다.


 


먼저 위치 정보를 수집하기 위해서 권한을 등록해야 한다.  manifest 을 열어서 보면...


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

그리고 다음은 gradle 파일에 추가해야할 부분은 


 


    implementation 'com.google.android.gms:play-services-location:19.0.1'

이제 코드를 구현해볼 차례인데, 


 


import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
.....

import com.google.android.gms.location.FusedLocationProviderClient;

.....

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
GoogleMap.OnMyLocationButtonClickListener,
GoogleMap.OnMarkerClickListener {

.....

private FusedLocationProviderClient fusedLocationClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

....

fusedLocationClient = LocationServices.getFusedLocationProviderClient(MapsActivity.this);

....
}

@Override
public void onMapReady(GoogleMap googleMap) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap = googleMap;
mMap.setOnMarkerClickListener(MapsActivity.this);
mMap.setOnMyLocationButtonClickListener(MapsActivity.this);
mMap.setMyLocationEnabled(true);
mUiSettings = googleMap.getUiSettings();
mUiSettings.setZoomControlsEnabled(true);
mUiSettings.setMyLocationButtonEnabled(true);

fusedLocationClient.getLastLocation()
.addOnSuccessListener(new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {

if (location == null) return ;

lat = location.getLatitude();
lon = location.getLongitude();

LatLng sydney = new LatLng(lat, lon);
markerBinding.markerText.setText(placeName);
mMap.addMarker(new MarkerOptions().position(sydney).title(placeName)
.icon(BitmapDescriptorFactory.fromBitmap(createDrawableFromView(getApplicationContext(), markView))));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 30));

...

}
});
}

...

}

 


이런 정도의 구현으로 fusedLocationClient 을 이용해서 최근 확인된 위치 정보를 가져오고 그것을 이옹해서 지도등에 위치 표시를 하는 용도로 사용해 볼 수 있다. 


 


 





 


사용한 예시는 이렇게 마무리 해 볼 수 있다.


 





오늘의 이야기

zxing

예전에도 살펴본 적이 있기는 하지만,

https://github.com/zxing/zxing/wiki/Getting-Started-Developing



 


GitHub - zxing/zxing: ZXing ("Zebra Crossing") barcode scanning library for Java, Android


ZXing ("Zebra Crossing") barcode scanning library for Java, Android - GitHub - zxing/zxing: ZXing ("Zebra Crossing") barcode scanning library for Java, Android


github.com





바코드 스캐너 기능을 구현하는 라이브러리는 감사할 따름이다. 이런 걸 모르면 어떻게 일일이 코딩을 다 할 수 도 없고, 아무튼지, 좋은 일이다. 나도 언제쯤에 이런 라이브러리 하나 만들어서 공유을 해 볼 수 있을런지,

오늘은 이 걸 이용해서 간단한 앱을 하나 만들어 보겠다. 한가지는 샘플 소스에서 custom 하게 구성해 보는 것을 따라해 볼 것이다.


 


먼저 gradle 파일에 추가를 해 보자.

dependencies {

    .....

    implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
    implementation 'com.google.zxing:core:3.4.1'

    .....
}

 


다음은 layout 을 구성해볼 차례인데,

 


내가 만드는 layout 은 다음 처럼 구성했다.




전에 다른 걸 할 때는 화면 전체를 바코드 읽기 위한 화면으로 활용을 했다면, custom 하게 수정을 하면 이렇게 화면의 일부만 바코드 스캔을 하는 화면으로 구성해 볼 수 있다는 점이 달라진다.


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 


 



이제 layout 을 보면 다음과 같이 구현 된다.


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ScanBarcodeActivity">

    <com.journeyapps.barcodescanner.DecoratedBarcodeView
        android:id="@+id/zxing_barcode_scanner"
        android:layout_width="371dp"
        android:layout_height="362dp"
        android:layout_alignParentStart="true"
        android:layout_alignParentEnd="true"
        android:layout_marginStart="16dp"
        android:layout_marginTop="12dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnFlash"
        app:zxing_scanner_layout="@layout/zxing_barcode_scanner">

    </com.journeyapps.barcodescanner.DecoratedBarcodeView>

    <ImageButton
        android:id="@+id/btnFlash"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="336dp"
        android:layout_marginTop="80dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/ic_baseline_flash_on_24" />

    <ImageButton
        android:id="@+id/btnHome"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="276dp"
        android:layout_marginTop="52dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/zxing_barcode_scanner"
        app:srcCompat="@drawable/ic_baseline_home_24" />

    <ImageButton
        android:id="@+id/btnLogout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="52dp"
        app:layout_constraintStart_toEndOf="@+id/btnHome"
        app:layout_constraintTop_toBottomOf="@+id/zxing_barcode_scanner"
        app:srcCompat="@drawable/ic_baseline_logout_24" />

</androidx.constraintlayout.widget.ConstraintLayout>

 


특별하게 봐야할 것은 zxing_scanner_layout 을 따로 지정하고 그것을 만들어 주어야 하는 부분이다. 아래와 같이 만들어 주면 되고, zxing_framing_rect_width, zxing_framing_rect_height 을 이용하여 화면 가운데 나오는 스캔 view 의 크기를 조정해 주면 사용자가 조금은 쉽게 바코드 인식을 할 수 있게 만들 수 있다.


<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:tools="http://schemas.android.com/tools"
       xmlns:app="http://schemas.android.com/apk/res-auto">

    <com.journeyapps.barcodescanner.BarcodeView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/zxing_barcode_surface"
        app:zxing_framing_rect_width="250dp"
        app:zxing_framing_rect_height="250dp"/>

    <com.journeyapps.barcodescanner.ViewfinderView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/zxing_viewfinder_view"
        app:zxing_possible_result_points="@color/zxing_custom_possible_result_points"
        app:zxing_result_view="@color/zxing_custom_result_view"
        app:zxing_viewfinder_laser="@color/zxing_custom_viewfinder_laser"
        app:zxing_viewfinder_laser_visibility="true"
        app:zxing_viewfinder_mask="@color/zxing_custom_viewfinder_mask"/>

    <TextView
        android:id="@+id/zxing_status_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        android:background="@color/zxing_transparent"
        android:text="@string/zxing_msg_default_status"
        android:textColor="@color/zxing_status_text"/>

</merge>

 


이제 실행을 위해서 activity을 구현해 보면 

Mainactivity 는 이렇게 만들면 된다.


import androidx.activity.result.ActivityResultLauncher;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.billcoreatech.databinding.ActivityMainBinding;
import com.google.zxing.client.android.Intents;
import com.journeyapps.barcodescanner.ScanContract;
import com.journeyapps.barcodescanner.ScanOptions;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());


        binding.btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                ScanOptions options = new ScanOptions().setOrientationLocked(false).setCaptureActivity(ScanBarcodeActivity.class);
                options.setBarcodeImageEnabled(true);
                options.setBeepEnabled(true);
                options.setPrompt(getString(R.string.msgScanTitle));
                barcodeLauncher.launch(options);

            }
        });
    }

    private final ActivityResultLauncher<ScanOptions> barcodeLauncher = registerForActivityResult(new ScanContract(),
            result -> {
                if(result.getContents() == null) {
                    Intent originalIntent = result.getOriginalIntent();
                    if (originalIntent == null) {
                        Log.d("MainActivity", "Cancelled scan");
                        Toast.makeText(MainActivity.this, "Cancelled", Toast.LENGTH_LONG).show();
                    } else if(originalIntent.hasExtra(Intents.Scan.MISSING_CAMERA_PERMISSION)) {
                        Log.d("MainActivity", "Cancelled scan due to missing camera permission");
                        Toast.makeText(MainActivity.this, "Cancelled due to missing camera permission", Toast.LENGTH_LONG).show();
                    }
                } else {
                    Log.d("MainActivity", "Scanned");
                    Toast.makeText(MainActivity.this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
                }
            });
}

 


ActivityResultLauncher 는 샘플 소스에서 그대로 복사해온 것이고, 이것을 부분을 이용하면 barcode 스캔 결과를 이용해서 다른 작업을 할 수 있다.


 


barcodeLauncher 에서 호출하는 ScanBarcodeActivity 소스는 다음과 같이 하면 되겠다.

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.billcoreatech.databinding.ActivityScanBarcodeBinding;
import com.journeyapps.barcodescanner.CaptureManager;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import com.journeyapps.barcodescanner.ViewfinderView;

import java.util.Random;

public class ScanBarcodeActivity extends AppCompatActivity implements DecoratedBarcodeView.TorchListener{

    ActivityScanBarcodeBinding binding ;
    private CaptureManager capture;
    SharedPreferences sp ;
    SharedPreferences.Editor flashStatus ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityScanBarcodeBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        sp = getSharedPreferences(getPackageName(), MODE_PRIVATE);

        binding.zxingBarcodeScanner.setTorchListener(this);
        if (!hasFlash()) {
            binding.btnFlash.setVisibility(View.GONE);
        }
        capture = new CaptureManager(this, binding.zxingBarcodeScanner);
        capture.initializeFromIntent(getIntent(), savedInstanceState);
        capture.setShowMissingCameraPermissionDialog(true);
        capture.decode();

        changeMaskColor(null);
        changeLaserVisibility(true);

        binding.btnHome.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
        binding.btnLogout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
        binding.btnFlash.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                switchFlashlight(view);
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        capture.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        capture.onPause();
    }

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

    @Override
    public void onBackPressed() {
        // super.onBackPressed();
        Toast.makeText(getApplicationContext(), getString(R.string.msgLogoutPress), Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        capture.onSaveInstanceState(outState);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return binding.zxingBarcodeScanner.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
    }

    /**
     * Check if the device's camera has a Flashlight.
     * @return true if there is Flashlight, otherwise false.
     */
    private boolean hasFlash() {
        return getApplicationContext().getPackageManager()
                .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
    }

    public void switchFlashlight(View view) {
        if (sp.getBoolean("flashOn", true)) {
            binding.zxingBarcodeScanner.setTorchOn();
        } else {
            binding.zxingBarcodeScanner.setTorchOff();
        }
    }

    public void changeMaskColor(View view) {
        Random rnd = new Random();
        int color = Color.argb(100, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
        binding.zxingBarcodeScanner.getViewFinder().setMaskColor(color);
    }

    public void changeLaserVisibility(boolean visible) {
        binding.zxingBarcodeScanner.getViewFinder().setLaserVisibility(visible);
    }

    @Override
    public void onTorchOn() {
        flashStatus = sp.edit();
        flashStatus.putBoolean("flashOn", false);
        flashStatus.commit();
        binding.btnFlash.setBackground(getDrawable(R.drawable.ic_baseline_flash_off_24));
    }

    @Override
    public void onTorchOff() {
        flashStatus = sp.edit();
        flashStatus.putBoolean("flashOn", true);
        flashStatus.commit();
        binding.btnFlash.setBackground(getDrawable(R.drawable.ic_baseline_flash_on_24));
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        capture.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

화면 예시에서 보았던 flash 버튼의 역활도 구현을 통해서 어두운 곳에서는 flash 을 켜거나, 끄거나 하는 기능도 기능해 볼 수 있다. zxingBarcodeScanner.setTorchOn / setTorchOff 을 통해서 구현이 가능 하다.





오늘의 이야기


#스하리1000명프로젝트,
韓国で迷子になりましたか?韓国語が話せなくても、このアプリを使えば簡単に移動できます。
あなたの言語で話すだけで、翻訳、検索が行われ、結果があなたの言語で表示されます。
旅行者に最適!英語、日本語、中国語、ベトナム語などを含む 10 以上の言語をサポートします。
今すぐ試してみましょう!
https://play.google.com/store/apps/details?id=com.billcoreatech.opdgang1127




2026/02/23

오늘의 이야기

예전에 listview 을 이용해서 화면에 정보를 표시하는 기능을 구현했다. 단순 목록 형태의 리스트 뷰이기 때문에 데이터를 여러개 보여줄 때 쉽게 사용할 수 있었기 때문이기도 하고... 뭐 아무튼지...


 


그러다가 recycleview 을 알게 되어 사용하면서 부터 여러가지 시도를 해 볼 수 있게 되었다. recycleview 의 경우 listview 처럼 쉽게 목록을 보여주기도 하지만, gridview 와 같이 바둑판 모양의 화면을 그려줄 수도 있다.  그래서 쉽게 화면의 모양을 구현할 수 있다는 것을 알게 되었다. 


 


 





 


실행되는 모습을 보면 마치 gridview 을 구현해 놓은 것 같지만, 실상은 recycleview 을 구현하고 모양만 변화를 주었을 뿐이다. 


        binding.listData.setAdapter(recyclerAdMobAdapter);
// binding.listData.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
binding.listData.setLayoutManager(new GridLayoutManager(getApplicationContext(), 3));
binding.listData.addItemDecoration(new GridSpacing(20, 20));

layoutmanager 을 LinearLayout 에서 GridLayoutManager 로 변경했을 뿐인데... 모양이 저렇게 변한 것이다. decoration 은 grid 모양일 때 간격을 두기 위해서 사용한 것이고, 딱히 다른 것을 한 것은 없는 것이라, 다양한 모양 변화를 줄 수 있어서 좋은 것 같다.


 


끝.


 


참고로 decoration 은 위한 소스는 아래와 같다.


import android.graphics.Rect;
import android.view.View;

import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

public class GridSpacing extends RecyclerView.ItemDecoration {
private int mSpacing;
private int mTopSpacing;

public GridSpacing(int spacing, int topSpacing) {
this.mSpacing = spacing;
this.mTopSpacing = topSpacing;
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
{
super.getItemOffsets(outRect, view, parent, state);
// Column Index
int index = ((GridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex();
// Item 포지션
int position = parent.getChildLayoutPosition(view);
if (index == 0) {
//좌측 Spacing 절반
outRect.right = mSpacing/ 2;
} else {
//우측 Spacing 절반
outRect.left = mSpacing/ 2;
} // 상단 탑 Spacing 맨 위에 포지션 0, 1은 Spacing을 안 줍니다.
if (position < 2) {
outRect.top = 0;
} else {
outRect.top = mTopSpacing;
}
}
}

 





오늘의 이야기



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

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

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

그것도 구글 Gemini로다가!

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

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

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


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




오늘의 이야기

 


달력이미지 구글링 결과



 


2022년이 새로 시작 되었는데, 책상위에 달력 하나는 두고 지내야겠지요 ?  이건 뭐 그냥 하는 말이지만, 늘 해 넘어갈 떄 쯤 회사에서 주는 달력이 제일 인 것 같기는 해요. 업무와 연관성도 있고, 


 


아무튼 임인년 한해도 좋은 일들만 함께하는 시간이길 바래 볼께요.


 


Happy New Year ... 다들 새해 복 많이 받으시고 좋은 일만...





오늘의 이야기

 


안드로이드 스튜디오



새로운 버전이 또 나왔네요. ㅋ... 이런다고 딱히 달라지는 것은 없는 것 같던데... 그래도 혹~  좋아진 것이 있는 지 살펴 볼까요?


 


Unified Gradle test runner 


 


Android Studio에서 테스트를 실행하는지 또는 지속적 통합 서버와 같은 Android Gradle 플러그인을 사용하여 명령줄에서 테스트를 실행하는지에 따라 한 실행기를 사용하여 테스트를 통과하고 다른 실행기를 사용하여 테스트가 실패하는 것과 같은 다른 테스트 결과를 볼 수 있습니다. 각각 다른 버전의 Android 계측 테스트 실행기를 구현하기 때문입니다.
 
이 문제를 해결하기 위해 이제 Android Studio Bumblebee는 테스트를 실행할 때 Gradle의 Android 계측 테스트 러너도 사용합니다. 따라서 로컬에서 테스트를 실행할 때 일관성을 기대해야 합니다. 이는 Gradle을 통해 실행되는 모든 단위 테스트를 도입한 Android Studio Arctic Fox와 유사한 변경 사항입니다.


 


New in Layout Inspector 


 


레이아웃 계층 스냅샷 캡처 Layout Inspector를 사용하면 실행 중인 앱의 레이아웃 계층 스냅샷을 저장할 수 있으므로 다른 사용자와 쉽게 공유하거나 나중에 참조할 수 있습니다. 스냅샷은 레이아웃의 상세한 3D 렌더링, View, Compose 또는 하이브리드 레이아웃의 구성 요소 트리, UI의 각 구성 요소에 대한 자세한 속성을 포함하여 Layout Inspector를 사용할 때 일반적으로 볼 수 있는 데이터를 캡처합니다. 스냅샷을 캡처하려면 Layout Inspector 도구 모음에서 스냅샷 내보내기를 클릭합니다.
레이아웃 계층 스냅샷 캡처 Android Studio Bumblebee에서 이제 레이아웃 검사기를 사용하여 Compose 레이아웃의 의미 체계 정보를 검사할 수 있습니다. Compose 노드를 선택할 때 속성 창을 사용하여 의미 체계 정보를 직접 선언하는지, 자식의 의미 체계를 병합하는지 또는 둘 다인지 확인합니다. 선언되거나 병합된 의미 체계를 포함하는 노드를 빠르게 식별하려면 구성 요소 트리 창에서 보기 옵션 드롭다운을 사용하고 의미 체계 계층 강조를 선택합니다.


 


New Device Manager


 


Device Manager는 Android Studio의 시작 화면에서 또는 프로젝트를 연 후 AVD Manager를 대체합니다. 장치 관리자는 유연한 도구 창, 가상 및 물리적 장치를 관리하기 위한 별도의 탭, 연결된 각 장치의 세부 정보와 같이 이 기능을 모든 로컬 테스트 장치를 보다 쉽게 만들고 관리할 수 있도록 하는 몇 가지 새로운 기능을 도입했습니다.
시작 화면에서 추가 작업 > 가상 장치 관리자를 선택하여 장치 관리자를 열고 프로젝트를 연 후 보기 > 도구 창 > 장치 관리자를 선택합니다.


 


New in App Inspection


 


작업, 알람 및 Wakelock 검사 백그라운드 작업 검사기를 사용하면 작업자 검사에 대한 기존 지원 외에도 앱의 작업, 알람 및 Wakelock을 검사할 수 있습니다. 이제 각 유형의 비동기 작업이 검사기 탭의 해당 제목 아래에 표시되어 해당 상태와 진행 상황을 쉽게 모니터링할 수 있습니다. 작업자와 유사하게 작업, 알람 또는 Wakelock을 선택하여 작업 세부 정보 패널에서 세부 정보를 검사할 수 있습니다.
네트워크 검사기 프로파일러 도구 창의 네트워크 프로파일러가 이제 앱 검사 도구 창으로 이동되었습니다. 이전에 네트워크 프로파일러를 사용한 적이 있다면 동일한 기능과 풍부한 네트워크 트래픽 데이터를 계속 사용할 수 있습니다. API 레벨 26 이상을 실행하는 기기에 앱을 배포하고 앱 검사기 > 네트워크 검사기 탭을 열기만 하면 됩니다.


 


Emulator runs inside Studio by default


 


이제 Android Emulator는 기본적으로 Android Studio 내에서 직접 실행됩니다. 이렇게 하면 화면 공간을 절약하는 데 도움이 되며 Android Studio를 종료하지 않고도 앱을 작성하고 테스트할 수 있습니다.
 
에뮬레이터가 실행 중일 때 장치 회전과 같은 일반적인 에뮬레이터 작업 및 탐색 재생과 같은 확장된 제어 옵션에 액세스할 수 있습니다.
 
대신 별도의 창에서 에뮬레이터를 실행하려면 파일 > 설정 > 도구 > 에뮬레이터로 이동하여 도구 창에서 실행을 선택 취소합니다.


 


Wireless debugging


 


이제 Android Studio는 Android 11 이상 기기에서 무선 디버깅 기능을 지원합니다. USB 케이블을 사용하거나 명령줄을 통해 ADB 연결을 관리하지 않고도 Wi-Fi를 통해 Android Studio에서 앱을 페어링하고 배포할 수 있습니다.


 


Compose interactive preview


 


이제 대화형 미리보기 기능이 기본적으로 활성화됩니다. 대화형 미리 보기를 사용하면 장치에서 작동하는 것처럼 미리 보기와 상호 작용할 수 있습니다. 대화형 미리 보기는 요소를 클릭하고 미리 보기에서 사용자 입력을 입력할 수 있는 샌드박스 환경에서 격리됩니다.


 


Animated Vector Drawable (AVD) preview


 


애니메이션 드로어블 미리보기 도구는 애니메이션 드로어블 리소스를 미리 볼 수 있는 기능을 제공합니다. 이 도구를 사용하면 개발자가 Android Studio에서 , 및 리소스를 즉시 미리 볼 수 있습니다.


 


 


새로 변경된 사항을 읽어 보았는데, 이전 버전에서 부터 지원 되고 있던 내용도 있고 하네요.  잠시 읽고 가보는 것으로...





오늘의 이야기

그것도 종이로 말이에요. ㅋㅋㅋ 이런일이 아직 갈길이 멀어요...