com.nbplus.vbroadlauncher.service.BroadcastChatHeadService.java Source code

Java tutorial

Introduction

Here is the source code for com.nbplus.vbroadlauncher.service.BroadcastChatHeadService.java

Source

/*
 * Copyright (c) 2015. NB Plus (www.nbplus.co.kr)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.nbplus.vbroadlauncher.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.os.PowerManager;
import android.speech.tts.TextToSpeech;
import android.support.v4.content.LocalBroadcastManager;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.webkit.WebView;
import android.widget.TextView;
import android.widget.Toast;

import com.nbplus.vbroadlauncher.R;
import com.nbplus.vbroadlauncher.data.Constants;
import com.nbplus.vbroadlauncher.data.LauncherSettings;
import com.nbplus.vbroadlauncher.data.PushPayloadData;
import com.nbplus.vbroadlauncher.hybrid.RealtimeBroadcastWebViewClient;
import com.nbplus.vbroadlauncher.hybrid.TextToSpeechHandler;

import org.basdroid.common.DeviceUtils;

import java.util.Locale;

/**
 * Created by basagee on 2015. 7. 14..
 */
public class BroadcastChatHeadService extends Service
        implements TextToSpeech.OnInitListener, TextToSpeechHandler.OnUtteranceProgressListener,
        RealtimeBroadcastWebViewClient.OnRealtimeBroadcastWebViewListener {
    private static final String TAG = BroadcastChatHeadService.class.getSimpleName();

    private WindowManager windowManager;
    private View mChatHead;
    private LayoutInflater inflater;

    private PushPayloadData mBroadcastData;
    private boolean mIsPlaying = false;

    // for audio broadcast
    WebView mWebView;
    RealtimeBroadcastWebViewClient mWebViewClient;

    // for text broadcast
    TextView mTextView;
    TextToSpeech mText2Speech;
    TextToSpeechHandler mText2SpeechHandler;

    private PowerManager.WakeLock mCpuWakeLock;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        inflater = LayoutInflater.from(this);
        mChatHead = null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        createBroadcastChatHead(intent);
        return super.onStartCommand(intent, flags, startId);
    }

    private void createBroadcastChatHead(Intent intent) {
        if (intent == null) {
            return;
        }

        mBroadcastData = intent.getParcelableExtra(Constants.EXTRA_BROADCAST_PAYLOAD_DATA);
        if (mBroadcastData == null) {
            Log.d(TAG, "Broadcast data is not found!!!");
            return;
        }
        long mBroadcastIndex = intent.getLongExtra(Constants.EXTRA_BROADCAST_PAYLOAD_INDEX, -1);
        String pushType = mBroadcastData.getServiceType();
        if (!Constants.PUSH_PAYLOAD_TYPE_NORMAL_BROADCAST.equals(pushType)
                && !Constants.PUSH_PAYLOAD_TYPE_REALTIME_BROADCAST.equals(pushType)
                && !Constants.PUSH_PAYLOAD_TYPE_TEXT_BROADCAST.equals(pushType)) {
            Log.d(TAG, "This is not broadcast push type !!!");
            return;
        }
        if (mIsPlaying && mChatHead != null) {
            removeChatHead(true);
        }

        mIsPlaying = true;

        int layout = -1;
        if (Constants.PUSH_PAYLOAD_TYPE_TEXT_BROADCAST.equals(pushType)) {
            layout = R.layout.fragment_text_broadcast;
        } else {
            layout = R.layout.fragment_audio_broadcast;
        }
        mChatHead = inflater.inflate(layout, null);

        if (Constants.PUSH_PAYLOAD_TYPE_TEXT_BROADCAST.equals(mBroadcastData.getServiceType())) {
            // ?
            mTextView = (TextView) mChatHead.findViewById(R.id.broadcast_text);
            mTextView.setText(mBroadcastData.getMessage());
            mTextView.setVerticalScrollBarEnabled(true);
            mTextView.setHorizontalScrollBarEnabled(false);
            mTextView.setMovementMethod(new ScrollingMovementMethod());

            mText2SpeechHandler = new TextToSpeechHandler(this, this);
            mText2Speech = new TextToSpeech(this, this);
        } else {
            // , ??
            mWebView = (WebView) mChatHead.findViewById(R.id.webview);
            mWebViewClient = new RealtimeBroadcastWebViewClient(this, mWebView, this);
            mWebViewClient.setBackgroundTransparent();

            String url = mBroadcastData.getMessage();
            if (url.indexOf("?") > 0) {
                if (!url.contains("UUID=")) {
                    url += ("&UUID=" + LauncherSettings.getInstance(this).getDeviceID());
                }
                if (!url.contains("APPID=")) {
                    url += ("&APPID=" + getApplicationContext().getPackageName());
                }
            } else {
                if (!url.contains("UUID=")) {
                    url += ("?UUID=" + LauncherSettings.getInstance(this).getDeviceID());
                }
                if (!url.contains("APPID=")) {
                    if (!url.contains("UUID=")) {
                        url += ("?APPID=" + getApplicationContext().getPackageName());
                    } else {
                        url += ("&APPID=" + getApplicationContext().getPackageName());
                    }
                }
            }
            mWebViewClient.loadUrl(url);
        }
        mChatHead.setTag(mBroadcastIndex);

        //        mChatHead.findViewById(R.id.btn_dismiss).setOnClickListener(new View.OnClickListener() {
        //            @Override
        //            public void onClick(View v) {
        //                removeChatHead();
        //            }
        //        });

        /**
         * To create an overlay view, when setting up the LayoutParams DON'T set the type to TYPE_SYSTEM_OVERLAY.
            
         Instead set it to TYPE_PHONE.
            
         Use the following flags:
         FLAG_NOT_TOUCH_MODAL
         FLAG_WATCH_OUTSIDE_TOUCH
         FLAG_NOT_TOUCH_MODAL << I found this one to be quite important. Without it,
         focus is given to the overlay and soft-key (home, menu, etc.) presses are not passed to the activity below.
         */
        int flag = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;

        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, flag, 0,
                PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.CENTER;

        /**
         * do not use...
        mChatHead.findViewById(R.id.txt_title).setOnTouchListener(new View.OnTouchListener() {
        private int initialX;
        private int initialY;
        private float initialTouchX;
        private float initialTouchY;
            
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    initialX = params.x;
                    initialY = params.y;
                    initialTouchX = event.getRawX();
                    initialTouchY = event.getRawY();
                    return true;
                case MotionEvent.ACTION_UP:
                    return true;
                case MotionEvent.ACTION_MOVE:
                    params.x = initialX + (int) (event.getRawX() - initialTouchX);
                    params.y = initialY + (int) (event.getRawY() - initialTouchY);
                    windowManager.updateViewLayout(mChatHead, params);
                    return true;
            }
            return false;
        }
        });
        */
        addChatHead(mChatHead, params);
    }

    public void addChatHead(View chatHead, WindowManager.LayoutParams params) {
        windowManager.addView(chatHead, params);
        acquireCpuWakeLock();
    }

    public void removeChatHead(boolean isForceByOther) {
        Log.d(TAG, "removeChatHead()");

        if (mText2Speech != null) {
            mText2Speech.shutdown();
        }
        mText2Speech = null;
        mText2SpeechHandler = null;

        if (mWebViewClient != null && isForceByOther) {
            mWebViewClient.onCloseWebApplicationByUser();
        }
        mWebViewClient = null;
        mWebView = null;

        releaseCpuLock();

        if (mChatHead != null) {
            windowManager.removeView(mChatHead);
            long broadcastIdx = (long) mChatHead.getTag();
            if (broadcastIdx > 0) {
                Intent i = new Intent();
                i.setAction(Constants.ACTION_BROADCAST_CHATHEAD_VIEW_DETACHED);
                i.putExtra(Constants.EXTRA_BROADCAST_PAYLOAD_INDEX, broadcastIdx);
                LocalBroadcastManager.getInstance(this).sendBroadcast(i);
            }
        }
        mChatHead = null;
        mIsPlaying = false;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        removeChatHead(false);
    }

    // TTS
    // for tts korean check
    @Override
    public void onInit(int status) {
        Log.d(TAG, "> TTS onInit()");

        if (status != TextToSpeech.SUCCESS) {
            Log.e(TAG, String.format("TextToSpeechManager.onInit(%d) fail!", status));
            Log.d(TAG, "   ??.... ? ??...");
            mText2Speech.shutdown();
            mText2Speech = null;

            // TODO : ? ?????
        } else {
            int result = mText2Speech.setLanguage(Locale.KOREA);
            if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                Log.e(TAG, String.format("TextToSpeech.setLanguage(%s) fail!", Locale.KOREA.getDisplayName()));

                // TODO : ? ?????
                mText2Speech.shutdown();
                mText2Speech = null;
            } else {
                mText2SpeechHandler.setTextToSpeechObject(mText2Speech);
                mText2SpeechHandler.play(mBroadcastData.getMessage());
            }
        }
    }

    @Override
    public void onStart(String s) {
        Log.d(TAG, "TTS onStart()");
        //        ((BaseActivity)getActivity()).dismissProgressDialog();
    }

    @Override
    public void onDone(String s) {
        Log.d(TAG, "TTS onDone()");
        removeChatHead(false);
    }

    @Override
    public void onError(String utteranceId, int errorCode) {
        Log.d(TAG, "TTS onError()");
        Toast.makeText(this, R.string.toast_tts_error, Toast.LENGTH_SHORT).show();
        removeChatHead(false);
    }

    public void acquireCpuWakeLock() {
        Log.e(TAG, "Acquiring cpu wake lock");
        if (mCpuWakeLock != null) {
            return;
        }

        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);

        mCpuWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP
                | PowerManager.ON_AFTER_RELEASE, "I'm your father");
        mCpuWakeLock.acquire();
    }

    public void releaseCpuLock() {
        Log.e(TAG, "Releasing cpu wake lock");

        if (mCpuWakeLock != null) {
            mCpuWakeLock.release();
            mCpuWakeLock = null;
        }
    }

    @Override
    public void onCloseWebApplication() {
        removeChatHead(false);
    }

    @Override
    public void onPageFinished(boolean success) {

    }

}