jp.mau.twappremover.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for jp.mau.twappremover.MainActivity.java

Source

package jp.mau.twappremover;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.jsoup.Connection;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.AssetManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;

import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.ImageLoader.ImageContainer;
import com.android.volley.toolbox.ImageLoader.ImageListener;
import com.android.volley.toolbox.Volley;

public class MainActivity extends Activity {
    private final String KEY_AUTH_TOKEN_TAG = "authenticity_token";
    private final String KEY_AUTH_TOKEN = "auth_token";
    private final String KEY_SESSION_ID = "_twitter_sess";
    private final String KEY_GUEST_ID = "guest_id";
    private final String KEY_HEADER_REVOKE = "btn_oauth_application_";
    private final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0";

    private final String TOP_PAGE = "https://twitter.com/";
    private final String LOGIN_PAGE = "https://twitter.com/sessions";
    private final String APP_PAGE = "https://twitter.com/settings/applications";
    private final String REVOKE_PAGE = "https://twitter.com/oauth/revoke";

    Handler _handler;
    ImageLoader _imageLoader;

    EditText _id;
    EditText _pass;
    AppAdapter _appadapter;

    DefaultHttpClient _client;
    String _auth_token; // HTML?authenticity_token
    String _cookie_auth; // Cookie???auth_token
    String _session_id; // Cookie???_twitter_sess
    String _guest_id;

    List<LinkedApp> _apps;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        _apps = new ArrayList<LinkedApp>();
        _handler = new Handler();
        _imageLoader = new ImageLoader(Volley.newRequestQueue(this), new BitmapCache());

        _id = (EditText) findViewById(R.id.activity_main_form_id);
        _pass = (EditText) findViewById(R.id.activity_main_form_pass);
        ListView list = (ListView) findViewById(R.id.activity_main_list);
        list.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
                final PopupView dialog = new PopupView(MainActivity.this);
                dialog.setDialog()
                        .setLabels(getString(R.string.activity_main_dlgtitle_revoke),
                                getString(R.string.activity_main_dlgmsg_revoke, _apps.get(position).name))
                        .setCancelable(true).setNegativeBtn(getString(R.string.activity_main_dlgbtn_revoke_cancel),
                                new OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        dialog.dismiss();
                                    }
                                })
                        .setPositiveBtn(getString(R.string.activity_main_dlgbtn_revoke_conf),
                                new OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        dialog.dismiss();
                                        new Thread(new Runnable() {
                                            @Override
                                            public void run() {
                                                revokeApp(_apps.get(position));
                                            }
                                        }).start();
                                    }
                                })
                        .show();
            }
        });
        setButton();

        _appadapter = new AppAdapter(this);
        list.setAdapter(_appadapter);

        _client = new DefaultHttpClient();
        HttpParams params = _client.getParams();
        HttpConnectionParams.setConnectionTimeout(params, 60 * 1000);
        HttpConnectionParams.setSoTimeout(params, 60 * 1000);
        _client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BEST_MATCH);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            ScrollView contents = new ScrollView(this);
            LinearLayout layout = new LinearLayout(this);
            layout.setOrientation(LinearLayout.VERTICAL);
            contents.addView(layout);
            AssetManager asm = getResources().getAssets();
            String[] filelist = null;
            try {
                filelist = asm.list("licenses");
            } catch (Exception ex) {
                ex.printStackTrace();
            }

            if (filelist != null) {
                for (String file : filelist) {
                    Gen.debug(file);
                    InputStream is = null;
                    BufferedReader br = null;
                    String txt = "";
                    try {
                        is = getAssets().open("licenses/" + file);
                        br = new BufferedReader(new InputStreamReader(is));
                        String str;
                        while ((str = br.readLine()) != null) {
                            txt += str + "\n";
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    } finally {
                        try {
                            if (is != null)
                                is.close();
                        } catch (Exception ex) {
                        }
                        try {
                            if (br != null)
                                br.close();
                        } catch (Exception ex) {
                        }
                    }
                    TextView tv = new TextView(this);
                    tv.setText(txt);
                    layout.addView(tv);
                }
            }

            // 
            final PopupView dialog = new PopupView(this);
            dialog.setDialog().setLabels(getString(R.string.activity_main_dlgtitle_oss), "")
                    .setView(contents, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
                    .setCancelable(true)
                    .setPositiveBtn(getString(R.string.activity_main_dlgbtn_oss), new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            dialog.dismiss();
                        }
                    }).show();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /** ?? */
    private void setButton() {
        Button btn = (Button) findViewById(R.id.activity_main_btn_submit);
        btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                reset();
                // ???
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
                if (_id.getText().length() < 1 || _pass.getText().length() < 1) {
                    // ???????
                } else {
                    //                ?
                    loginTask();
                }
            }
        });
    }

    private void reset() {
        _apps.clear();
        _appadapter.notifyDataSetChanged();
        _auth_token = null;
        _cookie_auth = null;
        _session_id = null;
        _guest_id = null;
    }

    private void loginTask() {
        final PopupView dialog = new PopupView(MainActivity.this);

        final AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
            @Override
            protected void onPreExecute() {
                dialog.show();
            }

            @Override
            protected Boolean doInBackground(Void... params) {
                _client.getConnectionManager().shutdown();
                _client = new DefaultHttpClient();
                HttpParams hparams = _client.getParams();
                HttpConnectionParams.setConnectionTimeout(hparams, 60 * 1000);
                HttpConnectionParams.setSoTimeout(hparams, 60 * 1000);
                _client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BEST_MATCH);

                getTopPage();
                // got session id and auth-token
                // login
                if (login()) {
                    getApps();
                } else {
                    return false;
                }
                return true;
            }

            @Override
            protected void onPostExecute(Boolean result) {
                dialog.dismiss();
                if (!result) {
                    // 
                    final PopupView dialog = new PopupView(MainActivity.this);
                    dialog.setDialog()
                            .setLabels(getString(R.string.activity_main_dlgtitle_loginfail),
                                    getString(R.string.activity_main_dlgmsg_loginfail))
                            .setCancelable(true).setPositiveBtn(getString(R.string.activity_main_dlgbtn_loginfail),
                                    new OnClickListener() {
                                        @Override
                                        public void onClick(View v) {
                                            dialog.dismiss();
                                        }
                                    })
                            .show();
                }
            }

        };

        dialog.setDialog().setLabels(getString(R.string.activity_main_dlgtitle_loading),
                getString(R.string.activity_main_dlgmsg_loading));

        task.execute();
    }

    private void getTopPage() {

        Document doc = null;
        try {
            Connection conn = Jsoup.connect(TOP_PAGE);
            conn.header("User-Agent", USER_AGENT);
            conn.header("Connection", "keep-alive");
            doc = conn.get();
            Response res = conn.response();
            Map<String, String> cookies = res.cookies();

            for (Map.Entry<String, String> e : cookies.entrySet()) {
                if (e.getKey().equals(KEY_SESSION_ID))
                    _session_id = e.getValue();
                if (e.getKey().equals(KEY_GUEST_ID))
                    _guest_id = e.getValue();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (doc == null)
            return;
        // parse top page and get authenticity token
        Elements forms = doc.getElementsByTag("form");
        for (Element e : forms) {
            Elements auths = e.getElementsByAttributeValue("name", "authenticity_token");
            if (auths.size() > 0) {
                _auth_token = auths.get(0).attr("value");
                break;
            }
        }
        if (_auth_token == null) {
            return;
        }
    }

    private boolean login() {
        HttpPost request = new HttpPost(LOGIN_PAGE);
        request.addHeader("User-Agent", USER_AGENT);
        request.addHeader("Referer", TOP_PAGE);
        request.addHeader("Content-Type", "application/x-www-form-urlencoded");
        request.addHeader("Cookie", "_twitter_sess=" + _session_id + "; guest_id=" + _guest_id);

        List<NameValuePair> pairs = new ArrayList<NameValuePair>();
        pairs.add(new BasicNameValuePair("session[username_or_email]", _id.getText().toString()));
        pairs.add(new BasicNameValuePair("session[password]", _pass.getText().toString()));
        pairs.add(new BasicNameValuePair("remember_me", "1"));
        pairs.add(new BasicNameValuePair("return_to_ssl", "true"));
        pairs.add(new BasicNameValuePair("redirect_after_login", " "));
        pairs.add(new BasicNameValuePair(KEY_AUTH_TOKEN_TAG, _auth_token));

        try {
            request.setEntity(new UrlEncodedFormEntity(pairs, "UTF-8"));
            String result = _client.execute(request, new ResponseHandler<String>() {
                @Override
                public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                    switch (response.getStatusLine().getStatusCode()) {
                    case HttpStatus.SC_OK:
                        return EntityUtils.toString(response.getEntity(), "UTF-8");
                    case HttpStatus.SC_NOT_FOUND:
                        throw new RuntimeException("not found");
                    default:
                        throw new RuntimeException("error");
                    }
                }
            });
            // ??(signin-wrapper???????)
            Document doc = Jsoup.parse(result);
            Elements elm = doc.getElementsByClass("signin-wrapper");
            if (elm.size() > 0)
                return false;

            // auth_token????
            List<Cookie> cookies = _client.getCookieStore().getCookies();
            for (Cookie c : cookies) {
                if (c.getName().equals(KEY_AUTH_TOKEN)) {
                    _cookie_auth = c.getValue();
                }
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return true;
    }

    private void getApps() {
        _apps.clear();

        HttpGet request = new HttpGet(APP_PAGE);
        request.addHeader("User-Agent", USER_AGENT);
        request.addHeader("Cookie", "_twitter_sess=" + _session_id + "; auth_token=" + _cookie_auth);

        try {
            String result = _client.execute(request, new ResponseHandler<String>() {
                @Override
                public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                    switch (response.getStatusLine().getStatusCode()) {
                    case HttpStatus.SC_OK:
                        return EntityUtils.toString(response.getEntity(), "UTF-8");
                    case HttpStatus.SC_NOT_FOUND:
                        throw new RuntimeException("not found");
                    default:
                        throw new RuntimeException("error");
                    }
                }
            });

            Document doc = null;
            doc = Jsoup.parse(result);

            // parse top page and get authenticity token
            Elements forms = doc.getElementsByTag("form");
            for (Element e : forms) {
                Elements auths = e.getElementsByAttributeValue("name", "authenticity_token");
                if (auths.size() > 0) {
                    _auth_token = auths.get(0).attr("value");
                    break;
                }
            }

            Elements apps = doc.getElementsByClass("app");
            for (Element e : apps) {
                LinkedApp app = new LinkedApp();
                if (e.getElementsByTag("strong").size() > 0)
                    app.name = e.getElementsByTag("strong").get(0).text();
                if (e.getElementsByClass("creator").size() > 0)
                    app.creator = e.getElementsByClass("creator").get(0).text();
                if (e.getElementsByClass("description").size() > 0)
                    app.desc = e.getElementsByClass("description").get(0).text();
                if (e.getElementsByClass("app-img").size() > 0)
                    app.imgUrl = e.getElementsByClass("app-img").get(0).attr("src");
                if (e.getElementsByClass("revoke").size() > 0) {
                    String tmp = e.getElementsByClass("revoke").get(0).attr("id");
                    app.revokeId = tmp.replaceAll(KEY_HEADER_REVOKE, "");
                } else {
                    // revoke id ????(facebook????????)
                    continue;
                }
                _apps.add(app);
            }
            _handler.post(new Runnable() {
                @Override
                public void run() {
                    _appadapter.notifyDataSetChanged();
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void revokeApp(LinkedApp app) {
        final PopupView dialog = new PopupView(this);
        dialog.setDialog().setLabels(getString(R.string.activity_main_dlgtitle_loading),
                getString(R.string.activity_main_dlgmsg_loading));
        _handler.post(new Runnable() {
            @Override
            public void run() {
                dialog.show();
            }
        });

        HttpPost request = new HttpPost(REVOKE_PAGE);
        request.addHeader("User-Agent", USER_AGENT);
        request.addHeader("Referer", APP_PAGE);
        request.addHeader("Content-Type", "application/x-www-form-urlencoded");
        request.addHeader("Cookie", "_twitter_sess=" + _session_id + "; auth_token=" + _cookie_auth);

        List<NameValuePair> pairs = new ArrayList<NameValuePair>();
        pairs.add(new BasicNameValuePair(KEY_AUTH_TOKEN_TAG, _auth_token));
        pairs.add(new BasicNameValuePair("scribeContext[component]", "oauth_app"));
        pairs.add(new BasicNameValuePair("token", app.revokeId));
        pairs.add(new BasicNameValuePair("twttr", "true"));
        try {
            request.setEntity(new UrlEncodedFormEntity(pairs, "UTF-8"));
            _client.execute(request, new ResponseHandler<String>() {
                @Override
                public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                    switch (response.getStatusLine().getStatusCode()) {
                    case HttpStatus.SC_OK:
                        return EntityUtils.toString(response.getEntity(), "UTF-8");
                    case HttpStatus.SC_NOT_FOUND:
                        throw new RuntimeException("not found");
                    default:
                        throw new RuntimeException("error");
                    }
                }
            });

        } catch (Exception ex) {
            ex.printStackTrace();
        }

        getApps();

        _handler.post(new Runnable() {
            @Override
            public void run() {
                dialog.dismiss();
            }
        });
    }

    @SuppressLint("NewApi")
    private void writeOut(String str) {
        FileOutputStream fos = null;
        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS),
                "test.txt");
        try {
            fos = new FileOutputStream(file);
            fos.write(str.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null)
                try {
                    fos.close();
                } catch (Exception e) {
                    ;
                }
        }
    }

    class LinkedApp {
        String name = "";
        String creator = "";
        String desc = "";
        String imgUrl = "";
        String revokeId = "";
    }

    class AppAdapter extends ArrayAdapter<LinkedApp> {
        LayoutInflater inf;

        public AppAdapter(Context context) {
            super(context, 0);
            inf = getLayoutInflater();
        }

        @Override
        public int getCount() {
            return _apps.size();
        }

        @SuppressLint("InflateParams")
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView != null) {
                holder = (ViewHolder) convertView.getTag();
            } else {
                convertView = inf.inflate(R.layout.list_applist, null);

                holder = new ViewHolder();
                holder.icon = (ImageView) convertView.findViewById(R.id.list_applist_image_icon);
                holder.name = (TextView) convertView.findViewById(R.id.list_applist_text_title);
                holder.creator = (TextView) convertView.findViewById(R.id.list_applist_text_author);
                holder.desc = (TextView) convertView.findViewById(R.id.list_applist_text_desc);
                convertView.setTag(holder);
            }
            LinkedApp target = _apps.get(position);
            holder.name.setText(target.name);
            holder.creator.setText(target.creator);
            holder.desc.setText(target.desc);

            ImageContainer container = (ImageContainer) holder.icon.getTag();
            if (container != null) {
                container.cancelRequest();
            }
            ImageListener listener = ImageLoader.getImageListener(holder.icon, android.R.drawable.ic_menu_gallery,
                    android.R.drawable.ic_dialog_alert);
            holder.icon.setTag(_imageLoader.get(target.imgUrl, listener));

            return convertView;
        }
    }

    class ViewHolder {
        ImageView icon;
        TextView name;
        TextView creator;
        TextView desc;
    }
}