com.gaze.webpaser.StackWidgetService.java Source code

Java tutorial

Introduction

Here is the source code for com.gaze.webpaser.StackWidgetService.java

Source

/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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.gaze.webpaser;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.microedition.khronos.opengles.GL;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;

public class StackWidgetService extends RemoteViewsService {
    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        return new StackRemoteViewsFactory(this.getApplicationContext(), intent);
    }
}

class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
    public static final String LOG_TAG = "widget_info";

    private static final int mCount = 10;
    private List<WidgetItem> mWidgetItems = new ArrayList<WidgetItem>();
    private Context mContext;
    private int mAppWidgetId;
    ArrayList<MainListItem> mlist = new ArrayList<MainListItem>();

    MemoryCache memoryCache = new MemoryCache();
    FileCache fileCache = new FileCache(mContext);

    InputStream inputStream = null;
    String result = "";
    String listUrl = GlobalData.PRELOAD_LIST_URL;

    public StackRemoteViewsFactory(Context context, Intent intent) {
        mContext = context;
        mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID);
    }

    public void onCreate() {

        Log.i(LOG_TAG, "onCreate");
        // In onCreate() you setup any connections / cursors to your data
        // source. Heavy lifting,
        // for example downloading or creating content etc, should be deferred
        // to onDataSetChanged()
        // or getViewAt(). Taking more than 20 seconds in this call will result
        // in an ANR.
        for (int i = 0; i < mCount; i++) {
            mWidgetItems.add(new WidgetItem(i + "!"));
        }

        if (GlobalData.globle_list != null) {
            if (GlobalData.globle_list.size() > 0) {

                mlist = GlobalData.globle_list;
            }
        }

        getDatafromNetwork();

        // We sleep for 3 seconds here to show how the empty view appears in the
        // interim.
        // The empty view is set in the StackWidgetProvider and should be a
        // sibling of the
        // collection view.
        // try {
        // Thread.sleep(3000);
        // } catch (InterruptedException e) {
        // e.printStackTrace();
        // }
    }

    private void getDatafromNetwork() {

        new AsyncTask<String, Void, String>() {

            @Override
            protected void onPreExecute() {

                super.onPreExecute();
                onStartDataLoading();
            }

            @Override
            protected String doInBackground(String... params) {

                ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();

                try {
                    // Set up HTTP post

                    // HttpClient is more then less deprecated. Need to change
                    // to
                    // URLConnection
                    HttpClient httpClient = new DefaultHttpClient();

                    HttpPost httpPost = new HttpPost(listUrl);
                    httpPost.setEntity(new UrlEncodedFormEntity(param));
                    HttpResponse httpResponse = httpClient.execute(httpPost);
                    HttpEntity httpEntity = httpResponse.getEntity();

                    Log.i(LOG_TAG, "finish http");

                    // Read content & Log
                    inputStream = httpEntity.getContent();
                } catch (UnsupportedEncodingException e1) {
                    Log.e("UnsupportedEncodingException", e1.toString());
                    e1.printStackTrace();
                } catch (ClientProtocolException e2) {
                    Log.e("ClientProtocolException", e2.toString());
                    e2.printStackTrace();
                } catch (IllegalStateException e3) {
                    Log.e("IllegalStateException", e3.toString());
                    e3.printStackTrace();
                } catch (IOException e4) {
                    Log.e("IOException", e4.toString());
                    e4.printStackTrace();
                }
                // Convert response to string using String Builder
                try {
                    BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"),
                            8);
                    StringBuilder sBuilder = new StringBuilder();

                    String line = null;
                    while ((line = bReader.readLine()) != null) {
                        sBuilder.append(line + "\n");
                    }

                    inputStream.close();
                    result = sBuilder.toString();

                    Log.i(LOG_TAG, "finish read stream: " + result);
                    if (!isStreamTheTargetJson(result)) {
                        result = "";
                        sBuilder.delete(0, sBuilder.length() - 1);
                    }

                    // parse json string here
                    if (!result.isEmpty()) {
                        if (result.startsWith("<html>"))
                            return "";

                        JSONObject titleJson = new JSONObject(result);
                        JSONArray datajson = titleJson.getJSONArray("data");
                        JSONArray urlQueue = datajson.getJSONArray(0);

                        for (int i = 0; i < urlQueue.length(); i++) {
                            JSONObject item = urlQueue.getJSONObject(i);
                            String url = item.getString("link");
                            String introtext = item.getString("introtext");
                            String title = item.getString("title");
                            String images = item.getString("images");
                            String name = item.getString("name");
                            String time = item.getString("publish_up");
                            if (url != null) {
                                // addToQueue(GlobalData.baseUrl+'/'+url);
                                addToList(url, introtext, title, images, name, time);
                            }
                        }
                    }

                } catch (Exception e) {
                    Log.e("StringBuilding & BufferedReader", "Error converting result " + e.toString());

                }
                return result;
            }

            @Override
            protected void onPostExecute(String msg) {
                // mDisplay.append(msg + "\n");
                Log.i(LOG_TAG, msg.toString());
                onFinishDataLoading();

            }

        }.execute();
    }

    protected void onFinishDataLoading() {
        // TODO Auto-generated method stub

    }

    protected void onStartDataLoading() {
        // TODO Auto-generated method stub

    }

    private boolean isStreamTheTargetJson(String result2) {
        if (result2 == null)
            return false;
        if (result2.contains("404 Not Found"))
            return false;

        JSONObject j;
        try {
            j = new JSONObject(result2);
            return (j.has("success") && (j.has("data")));
        } catch (JSONException e) {

            e.printStackTrace();
            return false;
        }
    }

    protected void addToList(String url, String introtext, String title, String images, String name, String time) {
        MainListItem item = new MainListItem(title, name, images, time, url, introtext);
        // mlist.add(item);

    }

    public void onDestroy() {
        // In onDestroy() you should tear down anything that was setup for your
        // data source,
        // eg. cursors, connections, etc.
        mWidgetItems.clear();
    }

    public int getCount() {
        // return mCount;
        return mlist.size();
    }

    public RemoteViews getViewAt(int position) {

        Log.i(LOG_TAG, "getViewAt " + position);
        // position will always range from 0 to getCount() - 1.

        // We construct a remote views item based on our widget item xml file,
        // and set the
        // text based on the position.
        RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.item_widget);
        rv.setTextViewText(R.id.textView_title, mlist.get(position).getTitle());
        String time = Util.getFormatTime(mlist.get(position).getTime());
        rv.setTextViewText(R.id.textView3_time, time);

        // Next, we set a fill-intent which will be used to fill-in the pending
        // intent template
        // which is set on the collection view in StackWidgetProvider.
        Bundle extras = new Bundle();
        extras.putInt(StackWidgetProvider.EXTRA_ITEM, position);
        Intent fillInIntent = new Intent();
        fillInIntent.putExtras(extras);
        rv.setOnClickFillInIntent(R.id.widget1, fillInIntent);

        // You can do heaving lifting in here, synchronously. For example, if
        // you need to
        // process an image, fetch something from the network, etc., it is ok to
        // do it here,
        // synchronously. A loading view will show up in lieu of the actual
        // contents in the
        // interim.
        // try {
        // System.out.println("Loading view " + position);
        // Thread.sleep(500);
        // } catch (InterruptedException e) {
        // e.printStackTrace();
        // }
        Bitmap bitmap = getBitmap(GlobalData.baseUrl + mlist.get(position).getImagePath());
        if (bitmap != null)
            rv.setImageViewBitmap(R.id.imageView1, bitmap);

        // Return the remote views object.
        return rv;
    }

    public RemoteViews getLoadingView() {
        // You can create a custom loading view (for instance when getViewAt()
        // is slow.) If you
        // return null here, you will get the default loading view.
        return null;
    }

    public int getViewTypeCount() {
        return 1;
    }

    public long getItemId(int position) {
        return position;
    }

    public boolean hasStableIds() {
        return true;
    }

    public void onDataSetChanged() {
        // This is triggered when you call AppWidgetManager
        // notifyAppWidgetViewDataChanged
        // on the collection view corresponding to this factory. You can do
        // heaving lifting in
        // here, synchronously. For example, if you need to process an image,
        // fetch something
        // from the network, etc., it is ok to do it here, synchronously. The
        // widget will remain
        // in its current state while work is being done here, so you don't need
        // to worry about
        // locking up the widget.
    }

    private Bitmap getBitmap(String url) {
        File f = fileCache.getFile(url);

        // from SD cache
        // CHECK : if trying to decode file which not exist in cache return null
        Bitmap b = decodeFile(f);
        if (b != null)
            return b;

        // Download image file from web
        try {

            Bitmap bitmap = null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is = conn.getInputStream();

            // Constructs a new FileOutputStream that writes to file
            // if file not exist then it will create file
            OutputStream os = new FileOutputStream(f);

            // See Utils class CopyStream method
            // It will each pixel from input stream and
            // write pixels to output stream (file)
            Util.CopyStream(is, os);

            os.close();
            conn.disconnect();

            // Now file created and going to resize file with defined height
            // Decodes image and scales it to reduce memory consumption
            bitmap = decodeFile(f);

            return bitmap;

        } catch (Throwable ex) {
            ex.printStackTrace();
            if (ex instanceof OutOfMemoryError)
                memoryCache.clear();
            return null;
        }
    }

    // Decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f) {

        try {

            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            FileInputStream stream1 = new FileInputStream(f);
            BitmapFactory.decodeStream(stream1, null, o);
            stream1.close();

            // Find the correct scale value. It should be the power of 2.

            // Set width/height of recreated image
            final int REQUIRED_SIZE = 150;

            int width_tmp = o.outWidth, height_tmp = o.outHeight;
            int scale = 1;
            while (true) {
                if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
                    break;
                width_tmp /= 2;
                height_tmp /= 2;
                scale *= 2;
            }

            // decode with current scale values
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;

            FileInputStream stream2 = new FileInputStream(f);
            Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
            stream2.close();
            return bitmap;

        } catch (FileNotFoundException e) {
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}