Android에서 ML Kit를 사용하여 항목 추출

텍스트 조각을 분석하고 그 안의 항목을 추출하려면 annotate() 메서드를 호출하고 텍스트 문자열 또는 EntityExtractionParams의 인스턴스를 전달합니다. 그러면 참조 시간, 시간대 또는 필터와 같은 추가 옵션을 지정하여 항목 유형의 하위 집합 검색을 제한할 수 있습니다. API는 각 항목에 대한 정보가 포함된 EntityAnnotation 객체 목록을 반환합니다.

SDK 이름항목 추출
구현기본 감지기의 애셋은 빌드 시간에 앱에 정적으로 연결됩니다.
애셋 크기의 영향항목 추출은 최대 5.6MB의 앱 크기에 영향을 미칩니다.

사용해 보기

  • 샘플 앱을 살펴보고 이 API의 사용 예를 확인합니다.

시작하기 전에

  1. 프로젝트 수준 build.gradle 파일에서 Google의 Maven 저장소가 buildscript 및 allprojects 섹션 모두에 포함되어 있는지 확인합니다.
  2. 모듈의 앱 수준 Gradle 파일(일반적으로 app/build.gradle)에 ML Kit 항목 추출 라이브러리의 종속 항목을 추가합니다.

    dependencies {
    // …
    
    implementation 'com.google.mlkit:entity-extraction:16.0.0-beta5'
    }
    

항목 추출

EntityExtractor 객체를 만들고 EntityExtractorOptions로 구성합니다.

Kotlin

val entityExtractor =
   EntityExtraction.getClient(
       EntityExtractorOptions.Builder(EntityExtractorOptions.ENGLISH)
           .build())

Java

EntityExtractor entityExtractor =
        EntityExtraction.getClient(
            new EntityExtractorOptions.Builder(EntityExtractorOptions.ENGLISH)
                .build());

EntityExtractorOptions는 필요한 경우 사용자 정의 Executor도 허용합니다. 그러지 않으면 ML Kit에서 기본 Executor가 사용됩니다.

필요한 모델이 기기에 다운로드되었는지 확인합니다.

Kotlin

entityExtractor
  .downloadModelIfNeeded()
  .addOnSuccessListener { _ ->
    /* Model downloading succeeded, you can call extraction API here. */
  }
  .addOnFailureListener { _ -> /* Model downloading failed. */ }

Java

entityExtractor
    .downloadModelIfNeeded()
    .addOnSuccessListener(
        aVoid -> {
          // Model downloading succeeded, you can call the extraction API here. 
        })
    .addOnFailureListener(
        exception -> {
          // Model downloading failed.
        });

모델이 다운로드되었는지 확인한 후 문자열 또는 EntityExtractionParamsannotate()에 전달합니다. 모델이 사용 가능한지 확인되기 전에는 annotate()를 호출하지 마세요.

Kotlin

val params =
      EntityExtractionParams.Builder("My flight is LX373, please pick me up at 8am tomorrow.")
        .setEntityTypesFilter((/* optional entity type filter */)
        .setPreferredLocale(/* optional preferred locale */)
        .setReferenceTime(/* optional reference date-time */)
        .setReferenceTimeZone(/* optional reference timezone */)
        .build()
entityExtractor
      .annotate(params)
      .addOnSuccessListener {
        // Annotation process was successful, you can parse the EntityAnnotations list here.
      }
      .addOnFailureListener {
        // Check failure message here.
      }

Java

EntityExtractionParams params = new EntityExtractionParams
        .Builder("My flight is LX373, please pick me up at 8am tomorrow.")
        .setEntityTypesFilter(/* optional entity type filter */)
        .setPreferredLocale(/* optional preferred locale */)
        .setReferenceTime(/* optional reference date-time */)
        .setReferenceTimeZone(/* optional reference timezone */)
        .build();
entityExtractor
        .annotate(params)
        .addOnSuccessListener(new OnSuccessListener<List<EntityAnnotation>>() {
          @Override
          public void onSuccess(List<EntityAnnotation> entityAnnotations) {
            // Annotation process was successful, you can parse the EntityAnnotations list here.
          }
        })
        .addOnFailureListener(new OnFailureListener() {
          @Override
          public void onFailure(@NonNull Exception e) {
            // Check failure message here.
          }
        });

PreferredLocale, ReferenceTime, ReferenceTimeZone는 DateTime 항목에만 영향을 미칩니다. 명시적으로 설정하지 않으면 사용자 기기의 값으로 기본 설정됩니다.

주석 결과를 루프 처리하여 인식된 항목에 대한 정보를 검색합니다.

Kotlin

for (entityAnnotation in entityAnnotations) {
  val entities: List<Entity> = entityAnnotation.entities

  Log.d(TAG, "Range: ${entityAnnotation.start} - ${entityAnnotation.end}")
  for (entity in entities) {
    when (entity) {
      is DateTimeEntity -> {
        Log.d(TAG, "Granularity: ${entity.dateTimeGranularity}")
        Log.d(TAG, "TimeStamp: ${entity.timestampMillis}")
      }
      is FlightNumberEntity -> {
        Log.d(TAG, "Airline Code: ${entity.airlineCode}")
        Log.d(TAG, "Flight number: ${entity.flightNumber}")
      }
      is MoneyEntity -> {
        Log.d(TAG, "Currency: ${entity.unnormalizedCurrency}")
        Log.d(TAG, "Integer part: ${entity.integerPart}")
        Log.d(TAG, "Fractional Part: ${entity.fractionalPart}")
      }
      else -> {
        Log.d(TAG, "  $entity")
      }
    }
  }
}

Java

List<EntityAnnotation> entityAnnotations = /* Get from EntityExtractor */;
for (EntityAnnotation entityAnnotation : entityAnnotations) {
  List<Entity> entities = entityAnnotation.getEntities();

  Log.d(TAG, String.format("Range: [%d, %d)", entityAnnotation.getStart(), entityAnnotation.getEnd()));
  for (Entity entity : entities) {
    switch (entity.getType()) {
      case Entity.TYPE_DATE_TIME:
        DateTimeEntity dateTimeEntity = entity.asDateTimeEntity();
        Log.d(TAG, "Granularity: " + dateTimeEntity.getDateTimeGranularity());
        Log.d(TAG, "Timestamp: " + dateTimeEntity.getTimestampMillis());
      case Entity.TYPE_FLIGHT_NUMBER:
        FlightNumberEntity flightNumberEntity = entity.asFlightNumberEntity();
        Log.d(TAG, "Airline Code: " + flightNumberEntity.getAirlineCode());
        Log.d(TAG, "Flight number: " + flightNumberEntity.getFlightNumber());
      case Entity.TYPE_MONEY:
        MoneyEntity moneyEntity = entity.asMoneyEntity();
        Log.d(TAG, "Currency: " + moneyEntity.getUnnormalizedCurrency());
        Log.d(TAG, "Integer Part: " + moneyEntity.getIntegerPart());
        Log.d(TAG, "Fractional Part: " + moneyEntity.getFractionalPart());
      case Entity.TYPE_UNKNOWN:
      default:
        Log.d(TAG, "Entity: " + entity);
    }
  }
}

EntityExtractor 객체가 더 이상 필요하지 않으면 close() 메서드를 호출합니다. Fragment 또는 AppCompatActivity에서 EntityExtractor를 사용하고 있다면 Fragment 또는 AppCompatActivity에서 LifecycleOwner.getLifecycle()을 호출한 다음 Lifecycle.addObserver를 호출하면 됩니다. 예를 들면 다음과 같습니다.

Kotlin

val options = …
val extractor = EntityExtraction.getClient(options);
getLifecycle().addObserver(extractor);

Java

EntityExtractorOptions options = …
EntityExtractor extractor = EntityExtraction.getClient(options);
getLifecycle().addObserver(extractor);

항목 추출 모델을 명시적으로 관리

위에서 설명한 대로 항목 추출 API를 사용하면 downloadModelIfNeeded()를 호출할 때 ML Kit가 필요에 따라 언어별 모델을 기기에 자동으로 다운로드합니다. ML Kit의 모델 관리 API를 사용하여 기기에서 사용할 수 있는 모델을 명시적으로 관리할 수도 있습니다. 이 방법은 모델을 미리 다운로드하려는 경우에 유용합니다. API를 사용하면 더 이상 필요하지 않은 모델을 삭제할 수도 있습니다.

Kotlin

val modelManager = RemoteModelManager.getInstance()

// Get entity extraction models stored on the device.
modelManager.getDownloadedModels(EntityExtractionRemoteModel::class.java)
  .addOnSuccessListener {
    // ...
  }
  .addOnFailureListener({
    // Error.
  })
    
// Delete the German model if it's on the device.
val germanModel =
  EntityExtractionRemoteModel.Builder(EntityExtractorOptions.GERMAN).build()
modelManager.deleteDownloadedModel(germanModel)
  .addOnSuccessListener({
    // Model deleted.
  })
  .addOnFailureListener({
    // Error.
  })
    
// Download the French model.
val frenchModel =
  EntityExtractionRemoteModel.Builder(EntityExtractorOptions.FRENCH).build()
val conditions =
  DownloadConditions.Builder()
    .requireWifi()
    .build()
modelManager.download(frenchModel, conditions)
  .addOnSuccessListener({
    // Model downloaded.
  })
  .addOnFailureListener({
    // Error.
  })

Java

// Get entity extraction models stored on the device.
modelManager.getDownloadedModels(EntityExtractionRemoteModel.class)
    .addOnSuccessListener(new OnSuccessListener<Set<EntityExtractionRemoteModel>>() {
      @Override
      public void onSuccess(Set<EntityExtractionRemoteModel> models) {
        // ...
      }
    })
    .addOnFailureListener(new OnFailureListener() {
      @Override
      public void onFailure(@NonNull Exception e) {
        // Error.
      }
    });

// Delete the German model if it's on the device.
EntityExtractionRemoteModel germanModel = new EntityExtractionRemoteModel.Builder(EntityExtractorOptions.GERMAN).build();
    modelManager.deleteDownloadedModel(germanModel)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
          @Override
          public void onSuccess(Void v) {
            // Model deleted.
          }
        })
        .addOnFailureListener(new OnFailureListener() {
          @Override
          public void onFailure(@NonNull Exception e) {
            // Error.
          }
        });

// Download the French model.
EntityExtractionRemoteModel frenchModel = new EntityExtractionRemoteModel.Builder(EntityExtractorOptions.FRENCH).build();
    DownloadConditions conditions = new DownloadConditions.Builder()
        .requireWifi()
        .build();
    modelManager.download(frenchModel, conditions)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
          @Override
          public void onSuccess(Void v) {
            // Model downloaded.
          }
        })
        .addOnFailureListener(new OnFailureListener() {
          @Override
          public void onFailure(@NonNull Exception e) {
            // Error.
          }
        });