안드로이드 앱에서 스토어 앱 기능 이용하기

안드로이드 앱 스토어는 많다. 안드로이드 개발자는 플레이 스토어, 아마존 스토어, 티스토어, 올레 마켓, 네이버 스토어 등이 있다는 것을 알고 있을 것이다. 국내는 저조하지만, 그들만의 생태계를 꾸려가고 있는 아마존은 그들의 생태계를 잘 만들고(안드로이드계의 애플(?)) 있는 것 같다. 자 이제 얼마나 많은 안드로이드 앱 스토어가 있는지는 다음의 링크로 확인해 보자.

그래서 안드로이드 앱을 개발하고 서비스 하다 보면, 플레이 스토어와 더불어 몇 개의 앱 스토어에 배포하는 경우가 종종 발생한다. 필자도 개발한 앱을 4개의 앱 스토어에 배포한다. 그래서 앱 스토어별로 바이너리를 빌드해야 한다. 빌드 방법은 다음을 참고해 보자.

본론으로 들어가 보자.
많은 회사가 하나 이상의 앱들을 마켓에 배포하고 있다. 물론 단일 마켓이 아니라 두개 이상의 마켓에 배포를 하는 경우도 많을 것이다. 그래서 아래의 기능을 좀 더 편리하게 지원하는 유틸리티 라이브러리를 개발했다. 기능은 다음과 같다.

  • 마켓 앱을 이용해서 서비스하는 앱을 확인하자
  • 마켓 앱을 이용해서 배포한 회사가 서비스하는 앱들을 확인하자
  • 마켓 앱을 이용해서 앱을 검색해보자
  • 마켓 앱이 없는 경우, 웹으로 위의 기능을 제공하자

이 기능을 사용하면, 앱에서 평가하기(별점주기), 변경내용 보기, 서비스하는 다른 앱 보여주기 등을 스토어 앱을 이용해서 제공할 수 있다. 그래서 아래 마켓을 대상으로 필요한 기능을 개발해 보자.
앱 스토어

이 기능을 개발하기 위해서는 스토어 앱이 제공하는 기능과 인터페이스를 확인해야 한다. 필요한 정보는 아래의 링크를 참고하면 된다.

이제 간단하게 설계를 해 보자. 앱에서 스토어 앱을 사용하는 형태이기에 스토어앱이라는 추상 클래스를 선언하고, 이 클래스를 상속해서 플레이 스토어 앱, 아마존 스토어 앱등을 만들어서 모듈화한다. 이 클래스의 구조는 다음과 같다.

이 구조에서 StoreApp.java와 PlayStoreApp.java를 살펴보고, 이 모듈을 사용하는 예를 보자.

package net.sjava.util.store;

import android.content.pm.PackageManager;

import java.util.Iterator;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
/**
 * 앱스토어 클래스 
 * 
 * @author mcsong@gmail.com
 * @date Dec 10, 2014 2:03:53 PM
 * @version 1.0.0
 */
public abstract class StoreApp {
	protected static final String PACKAGE_NAME_PLAY_OLD = "com.google.market";
	protected static final String PACKAGE_NAME_PLAY_NEW = "com.android.vending";
	protected static final String PACKAGE_NAME_AMAZON = "com.amazon.venezia";
	protected static final String PACKAGE_NAME_TSTORE = "com.skt.skaf.A000Z00040";
	protected static final String PACKAGE_NAME_NSTORE = "com.nhn.android.appstore";
	
	protected Intent intent;
	
	private List<ApplicationInfo> getApplications(Context ctx) {
		return ctx.getPackageManager().getInstalledApplications(
				PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
	}
	
	protected boolean isAppInstalled(Context ctx, String packageName) {
		Iterator<ApplicationInfo> itr = getApplications(ctx).iterator();
		while (itr.hasNext()) {
			if (itr.next().packageName.indexOf(packageName) != -1)
				return true;
		}
		
		return false;
	}
	
	/**
	 * 마켓 앱 설치여부를 리턴한다. 
	 * 
	 * @param ctx
	 * @return
	 */
	public abstract boolean isInstalled(Context ctx);
	
	/**
	 * 앱을 연다.
	 * 
	 * @param ctx
	 * @param uniqueId
	 */
	public abstract void openApp(Context ctx, String uniqueId);
	
	/**
	 * 앱을 검색한다. 
	 * 
	 * @param ctx
	 * @param keyword
	 */
	public abstract void searchApp(Context ctx, String keyword);
}
package net.sjava.util.store;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;

/**
 * 플레이 스토어 클래스 
 * 
 * @author mcsong@gmail.com
 * @date Dec 10, 2014 2:04:13 PM
 * @version 1.0.0
 */
public class PlayStoreApp extends StoreApp {
	static String APP_URL = "http://play.google.com/store/apps/deails?id=";
	static String APP_SEARCH_URL = "http://play.google.com/store/search?q=";
			
	public static PlayStoreApp newInstance() {
		return new PlayStoreApp();
	}
	
	@Override
	public boolean isInstalled(Context ctx) {
		return isAppInstalled(ctx, PACKAGE_NAME_PLAY_OLD)
				|| isAppInstalled(ctx, PACKAGE_NAME_PLAY_NEW);
	}

	@Override
	public void openApp(Context ctx, String uniqueId) {
		if(isInstalled(ctx)) {
			intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + uniqueId));
			ctx.startActivity(intent);
			return;			
		}

		intent = new Intent(Intent.ACTION_VIEW, Uri.parse(APP_URL + uniqueId));
		ctx.startActivity(intent);	
	}
		
	@Override
	public void searchApp(Context ctx, String keyword) {
		if(isInstalled(ctx)) {
			intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q="+ keyword));
			ctx.startActivity(intent);
			return;			
		}

		intent = new Intent(Intent.ACTION_VIEW, Uri.parse(APP_SEARCH_URL + keyword));
		ctx.startActivity(intent);
	}
	
	public void openPublisherApps(Context ctx, String keyword) {
		if(isInstalled(ctx)) {
			intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pub:"+ keyword));
			ctx.startActivity(intent);
			return;			
		}

		intent = new Intent(Intent.ACTION_VIEW, Uri.parse(APP_SEARCH_URL + "pub:" + keyword));
		ctx.startActivity(intent);	
	}
}

소스를 실행하면 다음의 화면을 볼 수 있다.

이 화면에서 버튼을 클릭하면 아래의 로직을 실행한다.

    	// tstore
    	if(vId == R.id.btn_tstore) {
    		//private static String pId = "0000320478";
    		store = TStoreApp.newInstance();
    		//store.openApp(this, "0000320478"); //  
    		store.searchApp(this, "facebook");
    		return;
    	}
    	
    	// amazon
    	if(vId == R.id.btn_amazon) {
    		store = AmazonStoreApp.newInstance();
    		//store.open(this, "com.amazon.mp3"); //  
    		//((AmazonStore)store).search(this, "mp3");
    		store.searchApp(this, "com.amazon.mp3");
    		return;
    	}
    	
    	// naver
    	if(vId == R.id.btn_nstore) {
    		store = NaverStoreApp.newInstance();
    		//store.openApp(this, "409160"); // 
    		store.searchApp(this, "naver");
    		return;
    	}
    }

이상 안드로이드 스토어 앱의 설치 여부를 확인하고, 설치된 경우 스토어 앱을 이용해서 기능을 제공하는 예제를 봤다. 이 소스는 SJava Appstore Util 에서 확인할 수 있다.

최신 소스 및 라이브러리는 https://github.com/mcsong/AppStoreLibrary 에서 확인하시고 사용하면 되겠다.

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.