jp.maju.wifiserver.client.ClientService.java Source code

Java tutorial

Introduction

Here is the source code for jp.maju.wifiserver.client.ClientService.java

Source

package jp.maju.wifiserver.client;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;

import org.apache.commons.codec.net.URLCodec;

import jp.maju.wifidetecter.reciever.ConnectionObserver;
import jp.maju.wifidetecter.reciever.ConnectionObserver.OnStateListener;
import jp.maju.wifiserver.CustomWebView;
import jp.maju.wifiserver.SocketInfo;
import jp.maju.wifiserver.twitter.TweetTask;
import jp.maju.wifiserver.twitter.TweetTask.OnTweetResultListener;
import jp.maju.wifiserver.twitter.TwitterUtils;
import jp.maju.wifiserver.util.CommonUtil;
import jp.maju.wifiserver.util.Logger;
import jp.maju.wifiserver.util.PreferenceUtil;
import twitter4j.Status;
import twitter4j.StatusUpdate;
import twitter4j.Twitter;
import android.app.Notification;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;

/*
 * Copyright {2014} {Matsuda Jumpei}
 * 
 * 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.
 */
public class ClientService extends Service implements OnStateListener {
    private static final String TAG = ClientService.class.getSimpleName();

    private static final int NOTIFICATION_ID = 0x34;

    private ConnectionObserver mClientObserver;
    private volatile Thread clientThread;
    private volatile Socket mSocket;
    private PrintWriter serverOutWriter;

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

    @Override
    public void onCreate() {
        super.onCreate();

        startForeground(NOTIFICATION_ID, new Notification());

        // mMessageHandler = new MessageHandler(this);
        mClientObserver = new ConnectionObserver();
        mClientObserver.setOnStateListener(this);

        registerReceiver(mClientObserver, CommonUtil.getNewIntentFilterWillBeRecieved());
    }

    @Override
    public void onDestroy() {
        if (mClientObserver != null) {
            unregisterReceiver(mClientObserver);
        }

        close();

        super.onDestroy();
    }

    @Override
    public void onDisabled() {
        close();
    }

    @Override
    public void onDisabling() {
        //        close();
    }

    @Override
    public void onEnabling() {
        //        close();
    }

    @Override
    public void onEnabled() {

    }

    @Override
    public void onUnknownState() {
        close();
    }

    @Override
    public void onConnected(NetworkInfo info) {
        launchClient();
    }

    @Override
    public void onConnecting(NetworkInfo info) {
        //        close();
    }

    @Override
    public void onDisconnectingOrOther(NetworkInfo info) {
        close();
    }

    private synchronized void launchClient() {
        SocketInfo si = PreferenceUtil.load(getApplication());

        if (si != null && clientThread == null) {
            clientThread = new Thread(new ClientWorker(si));
            clientThread.start();
        }
    }

    private class ClientWorker implements Runnable, OnTweetResultListener {
        private SocketInfo si;

        public ClientWorker(SocketInfo si) {
            this.si = si;
        }

        private boolean connect2Server() {
            int retryCount = 0;
            while (mSocket == null && retryCount < 10) {
                InetAddress serverAddr;

                try {
                    serverAddr = InetAddress.getByName(si.getHost());
                    // ProxyWrapper pWrapper =
                    // ProxyWrapper.getRegisteredProxy(getApplication(),
                    // CommonUtil.getCurrentSSID(getApplicationContext()));
                    // if (pWrapper != null) {
                    // Proxy proxy = new Proxy(Proxy.Type.SOCKS, new
                    // InetSocketAddress(pWrapper.host, pWrapper.port));
                    // mSocket = new Socket(proxy);
                    // InetSocketAddress dest = new
                    // InetSocketAddress(serverAddr, SERVER_PORT);
                    // mSocket.connect(dest);
                    // } else {
                    mSocket = new Socket(serverAddr, si.getPort());
                    // }

                    serverOutWriter = new PrintWriter(
                            new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream())), true);
                } catch (UnknownHostException e) {
                    Logger.e(TAG, e);
                } catch (IOException e) {
                    Logger.e(TAG, e);
                }

                retryCount++;
            }

            if (mSocket != null && retryCount <= 10) {
                Logger.d(TAG, "Server connection is available");
                return true;
            } else {
                Logger.d(TAG, "Server connection is not available");
                return false;
            }
        }

        @Override
        public void run() {
            if (!connect2Server()) {
                return;
            }

            doTweet();
        }

        private void doTweet() {
            Twitter twitter = TwitterUtils.getRegisteredTwitterInstance(getApplication(), false);

            String kind = PreferenceUtil.getAnchor(getApplication());

            if (kind == null) {
                return;
            }

            Logger.d(TAG, kind);

            if (twitter != null) {
                String msg = PreferenceUtil.getClientMessage(getApplication(), kind + "true");
                Logger.d(TAG, msg);

                if (System.currentTimeMillis() - 60 * 60 * 1000 < PreferenceUtil.getPreference(getApplication())
                        .getLong(kind + false, -1L)) {
                    return;
                }

                if (!PreferenceUtil.getPreference(getApplication()).getBoolean("isLogin", false)) {
                    Logger.d(TAG, "getPreference");
                    PreferenceUtil.getPreference(getApplication()).edit().putBoolean("isLogin", true).apply();

                    PreferenceUtil.getPreference(getApplication()).edit().putLong(kind + true, -1L).apply();
                }

                if (PreferenceUtil.isDifferentDate(getApplication(), kind + true)) {
                    Logger.d(TAG, "isDifferentDate");
                    PreferenceUtil.getPreference(getApplication()).edit().putBoolean("isLogin", true).commit();
                    TweetTask tTask = new TweetTask(twitter, true);
                    tTask.setOnTweetResultListener(this);
                    msg = msg.replace("${client}", "@null ")
                            .replace("${date}", CommonUtil.formatDate(System.currentTimeMillis())).toString();
                    StatusUpdate su = new StatusUpdate(msg);
                    tTask.exec(su);
                }
            }
        }

        @Override
        public void onPostedAll(boolean isLogin) {
            close();
        }

        @Override
        public void onPosted(Status status, boolean isLogin) {
            Logger.d(TAG, status.toString());
            sendMessage("tweet://" + status.getId() + ":" + status.getUser().getScreenName() + ":"
                    + PreferenceUtil.getUUID(getApplication()) + ":" + true);
        }
    }

    private void sendMessage(String msg) {
        if (mSocket != null && mSocket.isConnected() && !mSocket.isClosed()) {
            serverOutWriter.println(msg);
        }
    }

    private void close() {
        if (serverOutWriter != null) {
            serverOutWriter.close();
            serverOutWriter = null;
        }

        if (clientThread != null) {
            clientThread.interrupt();
            clientThread = null;
        }

        if (mSocket != null) {
            try {
                mSocket.shutdownInput();
                mSocket.shutdownOutput();
                mSocket.close();
            } catch (IOException e) {
                Logger.e(TAG, e);
            }
            mSocket = null;
        }
    }
}