하이브리드 앱 개발(Win32)

Cordova와 안드로이드 스튜디오를 이용하여 개발할때의 환경이다.
1. 프로젝트 생성

C:\CordovaBuild>cordova create mosaic-client
Creating a new cordova project.

┌──────────────────────────────────────────┐
│ Update available: 7.0.1 (current: 6.1.1) │
│ Run npm install -g cordova to update. │
└──────────────────────────────────────────┘

2. 플랫폼 추가
C:\CordovaBuild\mosaic-client>cordova platform add android
Adding android project…
Creating Cordova project for the Android platform:
Path: platforms\android
Package: io.cordova.hellocordova
Name: HelloCordova
Activity: MainActivity
Android target: android-23
Android project created with cordova-android@5.1.1
Discovered plugin “cordova-plugin-whitelist” in config.xml. Installing to the project
Fetching plugin “cordova-plugin-whitelist@1” via npm
Installing “cordova-plugin-whitelist” for android

This plugin is only applicable for versions of cordova-android greater than 4.0. If you have a previous platform version, you do *not* need this plugin since the whitelist will be built in.

3. Cordova 빌드
C:\CordovaBuild\mosaic-client>cordova build

4. 빌드된 프로젝트 복사
– 빌드된 폴더(C:\CordovaBuild\mosaic-client\platforms\android)를
프로젝트 생성할 폴더 (C:\Projects\22.MosaicSolutions\02.Solutions\MosaicAppSolution\mosaic-client) 로 복사

5. 안드로이드스튜디오에서 Open
안드로이드 스튜디오에서 해당 폴더를 Open 하여 실행

ajax로 대용량 데이터 전송시 길이 제한으로 인하여 에러 발생시

대량의 컨텐츠 데이터를 아래와 같이 JSON형태로 하여 $.ajax를 이용하여 전송시
var arrData = {‘data’: strData};
데이터의 용량이 2기가를 넘는다면 에러를 발생하게 되는데 톰캣의 경우는 아래와
같이 Server.xml에서 maxPostSize를 5기가 정도를 늘려주면 된다.
설정이 없다면 2097152(2 megabytes)가 디폴트이다.


La Farmacia Del Gallo del Dottor Bagnoli si trova in Largo Manfredi 7 nella frazione Siano ed è una delle 2 farmacie di Venosa. Oltre 200 farmaci in sviluppo e quando il Positivo-Farmaciaonline medico prescrive il dosaggio di clorochina.

구글 음성인식(SpeechRecognizer) API를 이용하여 서비스 형태로 구현하기

구글의 음성인식 API를 서비스 형태로 구현하여, 항상 명령어를 내리면 실행할수 있는지 테스트하기로 하였다.

1. 서비스 구현
– 구글의 SpeechRecognizer API는 한번 음성을 인식한 후, 끝나버리기 때문에 계속
재시작을 해주는 식으로 구현해야 한다.
– 따라서 다음과 같이 onResults에서 음성인식 결과를 출력하고 난후, 핸들러 메시지를
MSG_VOICE_RECO_END 상태로 보낸다.
그렇게되면 핸들러의 handleMessage() 에서는 1초후에 다시 SpeechRecognizer를
재시작한다.


public class VoiceRecoService extends Service
{
	
	@Override
	public void onCreate()
	{
		super.onCreate();
		startListening();
               ..... (중 략).....
	}
    
        ..... (중 략).....

	private Handler mHdrVoiceRecoState = new Handler()
	{
		@Override
		public void handleMessage(Message msg)
		{
			switch (msg.what)
			{
				case MSG_VOICE_RECO_READY	: break;
				case MSG_VOICE_RECO_END		:
				{
					stopListening();
					sendEmptyMessageDelayed(MSG_VOICE_RECO_RESTART, 1000);
					break;
				}
				case MSG_VOICE_RECO_RESTART	: startListening();	break;
				default:
					super.handleMessage(msg);
			}
		}
	};	

	public void startListening()
	{
		if(mBoolVoiceRecoStarted == false)
		{
		    if(mSrRecognizer == null)
		    {
			mSrRecognizer = SpeechRecognizer.createSpeechRecognizer(mCtxContext);
			mSrRecognizer.setRecognitionListener(mClsRecoListener);
		    }
		    if(mSrRecognizer.isRecognitionAvailable(mCtxContext))
		    {
			Intent itItent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
			itItent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
			itItent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.KOREAN.toString());
			itItent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 50);
			mSrRecognizer.startListening(itItent);
		    }
		}
		mBoolVoiceRecoStarted = true;
	}

	public void stopListening()
	{
		try
		{
			if (mSrRecognizer != null && mBoolVoiceRecoStarted == true)
			{
				mSrRecognizer.stopListening();
			}
		}
		catch(Exception ex)
		{
			Logger.e("Stop 예외:"+ StrUtil.trace(ex));
		}
		mBoolVoiceRecoStarted = false;
	}	


	private RecognitionListener mClsRecoListener = new RecognitionListener()
	{
		@Override
		public void onRmsChanged(float rmsdB)
		{
		}

		
		@Override
		public void onResults(Bundle results)
		{
			mHdrVoiceRecoState.sendEmptyMessage(MSG_VOICE_RECO_END);
			
			Intent itBroadcast = new Intent();
			itBroadcast.setAction(Constants.INTENT_ACTION_VOICE_RECO);        	
			itBroadcast.putExtras(results);
			mCtxContext.sendBroadcast(itBroadcast);
		}
		
		@Override
		public void onReadyForSpeech(Bundle params)
		{
		}

		@Override
		public void onEndOfSpeech()
		{
		}

		@Override
		public void onError(int intError)
		{
			mHdrVoiceRecoState.sendEmptyMessage(MSG_VOICE_RECO_END);
		}

		@Override
		public void onBeginningOfSpeech()
		{
		}

		@Override
		public void onBufferReceived(byte[] buffer)
		{
		}

		@Override
		public void onEvent(int eventType, Bundle params)
		{
		}

		@Override
		public void onPartialResults(Bundle partialResults)
		{
		}
	};
}

2. 결론
결론적으로 서비스로 구현가능함으로 확인하였으나, 음성을 인식하게 하기 위해
항상 대기상태로 만들어 놓았더니, 배터리 소모량이 많음을 확인하였다.

SC20150110-135825

안드로이드 버튼의 이미지를 그레이로 만들기

	
final Drawable daWork = mBtnWork.getCompoundDrawables()[1]; // 1번째가 TOP 이미지, 이유는 위에서 android:drawableTop으로 하였기때문에..
if(daWork != null) mBtnWork.setCompoundDrawables(null, convertToGrayscale(daWork), null, null);
    protected Drawable convertToGrayscale(Drawable drawable)
    {
        ColorMatrix cmMatrix = new ColorMatrix();
        cmMatrix.setSaturation(0); //0이면 grayscale
        drawable.setColorFilter(new ColorMatrixColorFilter(cmMatrix));
        return drawable;
    }

AppVersion Update(앱 버전 수동 업데이트)

Google Play Store 와 app.moram**.co* 에 App을 새로 올릴 때

AndroidManifest.xml 에 있는 android:versionCode="??"  확인한다.

그 후 Google Play Store 의 배포 지연 시간을 약 하루라고 생각하고 다음날

해당 DB의 MOB_UPDATE_INFO 테이블의 APP_VERSION 이라는 이름을 가진 코드의 참조값을

versionCode 의 값으로 바꿔준다.

 

그 이유는 사용자에게 새로운 프로덕션이 출시 되었으니 새롭게 다운로드하라는 의미이다.

정렬되지 않은 APK 파일(ZipAlign)

\\android-sdk\tools

폴더에 있는 ZipAlign을 이용하여 APK파일을 정렬해준다.

 

CMD 창을 관리자 권한으로 열어주고

경로는 \\android-sdk\tools  SDK가 있는 폴더로 이동해준다.

$>zipalign -f -v 4 ${input_name}.apk ${output_name}.apk

명령을 실행해주고 성공하면

Verification succesful 이라는 문구가 나온다

이후 ZipAlignedApps 폴더 안을 확인하면 ZipAlign이 완료된 APK파일을 얻을수 있다.

Android SDK Update 시 Eclipse Android S/W 대체 방법

Android SDK 에서 Tool 을 Update 한 뒤에 이클립스를 재시작시 

Android S/W 23.0.0 이상의 버전 또는 그 이상의 버전을 설치요구와 업데이트 확인을 요하는 경고 문구가 나오는 경우

 

이클립스

Help > Install New Software.. 메뉴로 이동하여

우측 하단에 already Installed 를 클릭하여 이미 설치된 S/W를 확인한다.

 

-Android DDMS

-Android Development Tools

-Android Hierarchy Viewer

-Android Native Development Tools

-Android Traceview

-Tracaer for OpenGL ES

 

위 6개의 항목을 선택한 뒤 Uninstall.. 해준다.

 

————————————————————————————————————–

이클립스 재시작이 완료되면

Help > Install New Software.. 메뉴로 이동하고

우측 상단에 Add 버튼을 클릭하고

Name : Android

Location : https://dl-ssl.google.com/android/eclipse/

위 내용을 입력하고

모든 항목을 설치한다.

No resource found that matches the given name ‘Theme.AppCompat.Light’.

error: Error retrieving parent for item: No resource found that matches the given name 'Theme.AppCompat.Light'. themes_XXX.xml /XXX/res/values line 8 Android AAPT Problem

 – 이클립스를 열어 FIle > Import > Android의 Existing Android Code Into Workspace를 선택

 – 안드로이드 SDK가 설치되어 있는 폴더에서 /extras/android/support/v7/appcompat 프로젝트를 임포트한다.

 – 해당 프로젝트의 프로퍼티의 Android에서 Libary에서 Add를 눌러 위에서 추가한 프로젝트를 추가한다.