org.esupportail.nfctagdroid.NfcTacDroidActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.esupportail.nfctagdroid.NfcTacDroidActivity.java

Source

/**
 * Licensed to ESUP-Portail under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for
 * additional information regarding copyright ownership.
 *
 * ESUP-Portail licenses this file to you 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 org.esupportail.nfctagdroid;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;

import android.nfc.NfcAdapter;
import android.nfc.Tag;

import android.os.Bundle;
import android.os.Process;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.webkit.ConsoleMessage;
import android.webkit.DownloadListener;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

import com.fasterxml.jackson.databind.ObjectMapper;

import org.apache.commons.io.IOUtils;
import org.esupportail.nfctagdroid.exceptions.NfcTagDroidException;
import org.esupportail.nfctagdroid.exceptions.NfcTagDroidInvalidTagException;
import org.esupportail.nfctagdroid.exceptions.NfcTagDroidPleaseRetryTagException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.esupportail.nfctagdroid.authentication.CsnAuthProvider;
import org.esupportail.nfctagdroid.authentication.DesfireAuthProvider;
import org.esupportail.nfctagdroid.beans.AuthResultBean;
import org.esupportail.nfctagdroid.localstorage.LocalStorageJavaScriptInterface;

import java.io.IOException;
import java.io.InputStream;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutionException;

import org.esupportail.nfctagdroid.exceptions.ExceptionHandler;
import org.esupportail.nfctagdroid.localstorage.LocalStorage;

public class NfcTacDroidActivity extends Activity implements NfcAdapter.ReaderCallback {

    private NfcAdapter mAdapter;
    public static String ESUP_NFC_TAG_SERVER_URL = null;
    public static String AUTH_TYPE;
    public static LocalStorage localStorageDBHelper;
    private static final Logger log = LoggerFactory.getLogger(NfcTacDroidActivity.class);
    private static WebView view;
    private static String url;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ESUP_NFC_TAG_SERVER_URL = getEsupNfcTagServerUrl(getApplicationContext());
        //To keep session for desfire async requests
        CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
        LocalStorage.getInstance(getApplicationContext());
        Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(getApplicationContext()));
        setContentView(R.layout.activity_main);
        mAdapter = NfcAdapter.getDefaultAdapter(this);
        checkHardware(mAdapter);
        localStorageDBHelper = LocalStorage.getInstance(this.getApplicationContext());
        String numeroId = localStorageDBHelper.getValue("numeroId");
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        String imei = telephonyManager.getDeviceId();
        url = ESUP_NFC_TAG_SERVER_URL + "/nfc-index?numeroId=" + numeroId + "&imei=" + imei + "&macAddress="
                + getMacAddr() + "&apkVersion=" + getApkVersion();
        view = (WebView) this.findViewById(R.id.webView);
        view.clearCache(true);
        view.addJavascriptInterface(new LocalStorageJavaScriptInterface(this.getApplicationContext()),
                "AndroidLocalStorage");
        view.addJavascriptInterface(new AndroidJavaScriptInterface(this.getApplicationContext()), "Android");

        view.setWebChromeClient(new WebChromeClient() {

            @Override
            public void onProgressChanged(WebView view, int progress) {
                if (progress == 100) {
                    AUTH_TYPE = localStorageDBHelper.getValue("authType");
                }
            }

            @Override
            public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
                log.info("Webview console message : " + consoleMessage.message());
                return false;
            }

        });

        view.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                view.reload();
                return true;
            }
        });
        view.getSettings().setAllowContentAccess(true);
        WebSettings webSettings = view.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setDatabaseEnabled(true);
        webSettings.setDatabasePath(this.getFilesDir().getParentFile().getPath() + "/databases/");

        view.setDownloadListener(new DownloadListener() {
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype,
                    long contentLength) {
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse(url));
                startActivity(i);
            }

        });

        view.setWebViewClient(new WebViewClient() {
            public void onPageFinished(WebView view, String url) {
            }
        });

        view.loadUrl(url);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

    public boolean isOnline() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        return netInfo != null && netInfo.isConnectedOrConnecting();
    }

    @Override
    protected void onPause() {
        super.onPause();
        log.info("Enter pause mode");
        view.loadUrl("about:blank");
        view.onPause();
        view.pauseTimers();
        mAdapter.disableReaderMode(this);
    }

    @Override
    public void onResume() {
        super.onResume();
        log.info("App is resume");
        view.onResume();
        view.loadUrl(url);
        view.resumeTimers();
        ESUP_NFC_TAG_SERVER_URL = getEsupNfcTagServerUrl(getApplicationContext());
        checkHardware(mAdapter);
        mAdapter.enableReaderMode(this, this,
                NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS, null);
    }

    @Override
    public void onTagDiscovered(final Tag tag) {
        if (localStorageDBHelper.getValue("readyToScan").equals("ok")) {

            localStorageDBHelper.updateValue("readyToScan", "ko");
            synchronized (tag) {
                String toastText = "";
                int rStatus = R.raw.fail;

                try {
                    AuthResultBean authResult = auth(tag);
                    toastText = authResult.getMsg();
                    if (authResult.isError()) {
                        log.warn(getString(R.string.log_msg_tag_ko));
                        localStorageDBHelper.updateValue("readyToScan", "ok");
                    } else {
                        rStatus = R.raw.success;
                        log.info(getString(R.string.log_msg_tag_ok) + " : "
                                + authResult.getMsg().replace("\n", " "));
                    }
                } catch (NfcTagDroidInvalidTagException e) {
                    log.info(getString(R.string.log_msg_invalid_auth), e);
                    toastText = getString(R.string.msg_tag_ko);
                    runOnUiThread(ToastThread.getInstance(getApplicationContext(), rStatus, toastText));

                } catch (NfcTagDroidPleaseRetryTagException e) {
                    log.warn(getString(R.string.log_msg_retry_auth), e);
                    toastText = getString(R.string.msg_retry);
                    runOnUiThread(ToastThread.getInstance(getApplicationContext(), rStatus, toastText));

                } catch (Exception e) {
                    log.error(getString(R.string.log_msg_unknow_err), e);
                    toastText = getString(R.string.msg_unknow_err);
                    runOnUiThread(ToastThread.getInstance(getApplicationContext(), rStatus, toastText));
                    localStorageDBHelper.updateValue("readyToScan", "ok");

                }
                MediaPlayer mp = MediaPlayer.create(getApplicationContext(), rStatus);
                mp.start();
            }
        } else {
            log.warn("onTagDiscovered but localStorageDBHelper.getValue(\"readyToScan\") = "
                    + localStorageDBHelper.getValue("readyToScan"));
        }

    }

    protected AuthResultBean auth(Tag tag) throws ExecutionException, InterruptedException {

        AuthResultBean authResult = null;
        if (tag != null) {
            String response = null;
            if (AUTH_TYPE.equals("DESFIRE")) {
                DesfireAuthProvider desfireAuthProvider = new DesfireAuthProvider();
                response = desfireAuthProvider.desfireAuth(tag);
            } else if (AUTH_TYPE.equals("CSN")) {
                CsnAuthProvider csnAuthProvider = new CsnAuthProvider();
                response = csnAuthProvider.csnAuth(tag);
            }

            try {
                authResult = new ObjectMapper().readValue(response, AuthResultBean.class);
            } catch (IOException e) {
                throw new NfcTagDroidException(getString(R.string.msg_json_err), e);
            }
        }
        return authResult;
    }

    public boolean checkHardware(NfcAdapter mAdapter) {
        if (mAdapter == null) {
            Toast.makeText(this, getString(R.string.msg_error_nfc), Toast.LENGTH_LONG).show();
            finish();
            return false;
        }

        if (!mAdapter.isEnabled()) {
            Toast.makeText(this, getString(R.string.msg_activ_nfc), Toast.LENGTH_LONG).show();
            startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
        }

        if (!isOnline()) {
            view.loadUrl("about:blank");
            Toast.makeText(this, getString(R.string.msg_activ_network), Toast.LENGTH_LONG).show();
            startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
        }
        return true;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle(R.string.exit)
                    .setMessage(R.string.msg_exit)
                    .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                            Process.killProcess(Process.myPid());
                            System.exit(1);
                        }

                    }).setNegativeButton(R.string.no, null).show();
        }
        return true;
    }

    private String getApkVersion() {
        String version = "unknow";
        try {
            PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
            version = pInfo.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            throw new NfcTagDroidException(getString(R.string.msg_getApkVersion_err), e);
        }
        return version;
    }

    private static String getEsupNfcTagServerUrl(Context context) {
        try {
            InputStream esupnfctagPropertiesFile = context.getAssets().open("esupnfctag.properties");
            Properties props = new Properties();
            props.load(esupnfctagPropertiesFile);
            String esupNfcTagServerUrl = props.getProperty("esupNfcTagServerUrl");
            return esupNfcTagServerUrl;
        } catch (IOException e) {
            throw new NfcTagDroidException(
                    "can't get esupNfcTagServerUrl property from esupnfctag.properties file !", e);
        }
    }

    public static String getMacAddr() {
        try {
            List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface nif : all) {
                if (!nif.getName().equalsIgnoreCase("wlan0"))
                    continue;

                byte[] macBytes = nif.getHardwareAddress();
                if (macBytes == null) {
                    return "";
                }

                StringBuilder res1 = new StringBuilder();
                for (byte b : macBytes) {
                    res1.append(Integer.toHexString(b & 0xFF) + ":");
                }

                if (res1.length() > 0) {
                    res1.deleteCharAt(res1.length() - 1);
                }
                return res1.toString();
            }
        } catch (Exception e) {
            throw new NfcTagDroidException("can't get mac address", e);
        }
        return "";
    }
}