com.github.wakhub.monodict.activity.settings.DownloadsActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.github.wakhub.monodict.activity.settings.DownloadsActivity.java

Source

/**
 * Copyright (C) 2014 wak
 *
 * 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.github.wakhub.monodict.activity.settings;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Environment;
import android.text.util.Linkify;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.github.wakhub.monodict.R;
import com.github.wakhub.monodict.activity.BrowserActivity;
import com.github.wakhub.monodict.activity.bean.ActivityHelper;
import com.github.wakhub.monodict.activity.bean.CommonActivityTrait;
import com.github.wakhub.monodict.json.Downloads;
import com.github.wakhub.monodict.json.DownloadsItem;
import com.github.wakhub.monodict.preferences.Dictionary;
import com.github.wakhub.monodict.preferences.Preferences_;
import com.google.gson.Gson;

import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.HttpsClient;
import org.androidannotations.annotations.ItemClick;
import org.androidannotations.annotations.OnActivityResult;
import org.androidannotations.annotations.OptionsItem;
import org.androidannotations.annotations.OptionsMenu;
import org.androidannotations.annotations.res.DimensionRes;
import org.androidannotations.annotations.res.StringRes;
import org.androidannotations.annotations.sharedpreferences.Pref;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

// TODO: refactoring
@EActivity(R.layout.activity_downloads)
@OptionsMenu({ R.menu.downloads })
public class DownloadsActivity extends ListActivity {

    private static final String TAG = BrowserActivity.class.getSimpleName();

    final public static String RESULT_INTENT_ENGLISH = "english";
    final public static String RESULT_INTENT_FILENAME = "filename";
    final public static String RESULT_INTENT_PATH = "path";

    private static final int REQUEST_CODE_DOWNLOAD = 10120;

    @Pref
    Preferences_ preferences;

    @Bean
    CommonActivityTrait commonActivityTrait;

    @Bean
    ActivityHelper activityHelper;

    @HttpsClient
    HttpClient httpsClient;

    @DimensionRes
    float spaceRelax;

    @StringRes
    String appName;

    private File sdCard;

    private Intent resultIntent;

    private DownloadTask dlTask;

    private ArrayAdapter<DownloadsItem> listAdapter;

    private ProgressDialog progressDialog;

    @AfterViews
    void afterViews() {
        commonActivityTrait.initActivity(preferences);
        getActionBar().setDisplayHomeAsUpEnabled(true);

        sdCard = Environment.getExternalStorageDirectory();

        resultIntent = getIntent();
        dlTask = new DownloadTask();

        listAdapter = new ArrayAdapter<DownloadsItem>(this, android.R.layout.simple_list_item_2,
                android.R.id.text1) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View view = super.getView(position, convertView, parent);
                DownloadsItem item = getItem(position);

                TextView text1 = (TextView) view.findViewById(android.R.id.text1);
                text1.setText(Dictionary.EMOJI + item.getName());

                TextView text2 = (TextView) view.findViewById(android.R.id.text2);
                text2.setText(String.format("%s\nsize: %s", item.getDescription(), item.getSize()));

                return view;
            }
        };
        setListAdapter(listAdapter);

        Downloads downloads = null;
        try {
            InputStream inputStream = getAssets().open("downloads.json");
            downloads = (new Gson()).fromJson(IOUtils.toString(inputStream), Downloads.class);
        } catch (IOException e) {
            activityHelper.showError(e);
            return;
        }
        listAdapter.addAll(downloads.getItems());
    }

    @OnActivityResult(REQUEST_CODE_DOWNLOAD)
    void onActivityResultDownload(int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            return;
        }
        setResult(RESULT_OK, data);
        finish();
    }

    @OptionsItem(R.id.action_help)
    void onActionHelp() {
        activityHelper.buildNoticeDialog(activityHelper.getStringFromRaw(R.raw.downloads_help))
                .setTitle(R.string.title_help).show();
    }

    @ItemClick(android.R.id.list)
    void onClickListItem(int position) {
        final DownloadsItem item = listAdapter.getItem(position);
        TextView textView = new TextView(this);
        textView.setAutoLinkMask(Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES);
        textView.setPadding((int) spaceRelax, (int) spaceRelax, (int) spaceRelax, (int) spaceRelax);
        textView.setText(String.format("%s\nsize: %s", item.getDescription(), item.getSize()));
        ScrollView scrollView = new ScrollView(this);
        scrollView.addView(textView);

        new AlertDialog.Builder(this)
                .setPositiveButton(R.string.action_download, new AlertDialog.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        resultIntent.putExtra(RESULT_INTENT_ENGLISH, item.isEnglish());
                        resultIntent.putExtra(RESULT_INTENT_FILENAME, item.getName());
                        startDownload(item);
                    }
                }).setNegativeButton(android.R.string.cancel, null).setIcon(R.drawable.ic_action_download)
                .setTitle(item.getName()).setView(scrollView).show();
    }

    void startDownload(DownloadsItem downloadsItem) {
        progressDialog = new ProgressDialog(this);
        progressDialog.setTitle(R.string.message_in_processing);
        progressDialog.setIndeterminate(true);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setCancelable(false);

        dlTask.execute(downloadsItem.getUrl());
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        if (commonActivityTrait.onMenuItemSelected(featureId, item)) {
            return true;
        }
        return super.onMenuItemSelected(featureId, item);
    }

    class DownloadTask extends AsyncTask<String, Integer, String> {

        @Override
        protected void onPreExecute() {
            progressDialog.show();
        }

        @Override
        protected String doInBackground(String... params) {
            String filename = downloadDicfile(params[0], true);
            return filename;
        }

        @Override
        protected void onPostExecute(String result) {
            progressDialog.dismiss();

            if (result != null) {
                Toast.makeText(DownloadsActivity.this, R.string.message_download_succeed, Toast.LENGTH_LONG).show();
                resultIntent.putExtra(RESULT_INTENT_PATH, result);
                setResult(RESULT_OK, resultIntent);
            } else {
                Toast.makeText(DownloadsActivity.this, R.string.message_download_failed, Toast.LENGTH_LONG).show();
            }
            dlTask = null;
            finish();
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            progressDialog.setProgress(progress[0]);
            if (progress[1] > 0) {
                progressDialog.setIndeterminate(false);
                progressDialog.setMax(progress[1]);
            } else {
                progressDialog.setIndeterminate(true);
                progressDialog.setMax(1);
            }
        }

        private String getName(String path) {
            String[] patharr = path.split("/");

            return patharr[patharr.length - 1];
        }

        private String downloadDicfile(String url, boolean zip) {

            String ret = null;
            Log.d(TAG, "downloadDicfile: " + url);
            try {
                // HTTP GET 
                HttpUriRequest httpGet = new HttpGet(url);
                HttpClient httpClient = null;
                if (url.startsWith("https://")) {
                    httpClient = httpsClient;
                } else {
                    httpClient = new DefaultHttpClient();
                }

                HttpConnectionParams.setSoTimeout(httpClient.getParams(), 30000);
                HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), 30000);

                HttpResponse httpResponse = httpClient.execute(httpGet);
                int status = httpResponse.getStatusLine().getStatusCode();
                Log.d(TAG, "HTTP status: " + status);
                if (status != HttpStatus.SC_OK) {
                    return ret;
                }
                InputStream is = httpResponse.getEntity().getContent();
                int length = (int) httpResponse.getEntity().getContentLength();
                String filePath = sdCard.getPath() + "/" + appName + "/" + getName(url);
                Log.d(TAG, "The file will be saved as " + filePath);
                File f = new File(filePath);
                f.getParentFile().mkdir();

                FileOutputStream fos = new FileOutputStream(f);

                byte[] buff = new byte[4096];
                int len;
                int offset = 0;
                int lastOffset = 0;
                for (;;) {
                    len = is.read(buff);
                    if (len == -1)
                        break;
                    fos.write(buff, 0, len);
                    offset += len;

                    // update progress bar
                    if (offset - lastOffset > 1024 * 16) {
                        publishProgress(offset, length);
                        lastOffset = offset;
                    }
                }
                fos.close();
                is.close();

                if (url.endsWith(".zip") || zip) {
                    ret = extractZip(f);
                    f.delete();
                } else {
                    ret = f.getPath();
                }
            } catch (IOException e) {
                Log.d(TAG, e.toString());
            }

            return ret;
        }

        private String extractZip(File f) {
            Log.d(TAG, "extractZip: " + f.getName());
            String ret = null;
            ZipInputStream zis;
            try {
                zis = new ZipInputStream(new FileInputStream(f));
                ZipEntry ze;
                while (ret == null && (ze = zis.getNextEntry()) != null) {
                    String name = ze.getName();

                    if (name.toLowerCase().endsWith(".dic")) {
                        File nf = new File(sdCard.getPath() + "/" + appName + "/" + getName(name));
                        nf.getParentFile().mkdir();

                        FileOutputStream fos = new FileOutputStream(nf);

                        byte[] buff = new byte[512];
                        int len;
                        int offset = 0;
                        int lastOffset = 0;

                        for (;;) {
                            len = zis.read(buff);
                            if (len == -1)
                                break;
                            fos.write(buff, 0, len);
                            offset += len;

                            // update progress bar
                            if (offset - lastOffset > 1024 * 16) {
                                publishProgress(offset, 0);
                                lastOffset = offset;
                            }
                        }
                        fos.close();
                        ret = nf.getPath();
                    }
                    zis.closeEntry();
                }
                zis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            Log.d(TAG, "Finished extract");
            return ret;
        }
    }
}