Java tutorial
/* Copyright (c) 2010 Park "segfault" Joon-Kyu * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ package org.planetmono.dcuploader; 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.UnsupportedEncodingException; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.net.SocketTimeoutException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.InputStreamBody; import org.apache.http.entity.mime.content.StringBody; import org.planetmono.dcuploader.exceptions.*; import android.app.Activity; import android.app.AlertDialog; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; import android.content.res.TypedArray; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Bitmap.CompressFormat; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.media.ExifInterface; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.provider.MediaStore; import android.util.Log; import android.view.ContextMenu; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.ContextMenu.ContextMenuInfo; import android.view.View.OnClickListener; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; import android.widget.Gallery; import android.widget.ImageView; import android.widget.Toast; import android.widget.CompoundButton.OnCheckedChangeListener; public class ActivityUploader extends Activity { private static final String GALL_URL = "http://gall.dcinside.com"; private static final String FORM_URL = "http://gall.dcinside.com/article_write.php"; private static final String LOGIN_STATUS_URL = "http://gn.dcinside.com/gn_top_gall_right_write.php"; private static final String UPLOAD_URL = "http://upload.dcinside.com/g_write.php"; private static final String UPLOAD_IMAGE_URL = "http://upload.dcinside.com/upload_imgFree.php"; private static final String AGE_VERIFICATION_URL = "http://cert.namecheck.co.kr/certnc_inner_write.asp"; private static final int MENU_GROUP_SELECT_GALLERY = 0; private static final int MENU_ADD_GALLERY = -1; private static final int MENU_GROUP_VISIT = 1; private static final int MENU_DCINSIDE = 0; private static final int MENU_MOBILE = 1; private static final String STAMP_MODEL = " (using " + Build.MODEL + ")"; private int maximumResolution; private int imageQuality; private int sizeThreshold; private String mobilePageProvider; private String pageDestination; private ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>(); private String postfix = ""; private String mapstring = ""; private int destination = 0; private int targetNo = 0; private boolean called = false; private boolean passThrough = false; private boolean galleryChanged = false; /* must be kept */ private File tempFile = null; private String target = null; private ArrayList<Uri> contents = new ArrayList<Uri>(); private ArrayList<String> tempFiles = new ArrayList<String>(); /* progress dialogs */ private GenericProgressHandler uploadProgressDialog = new GenericProgressHandler(ActivityUploader.this, " "); private GenericProgressHandler signOffProgressDialog = new GenericProgressHandler(ActivityUploader.this, " "); /* For saving form data when orientation changes */ String formGallery = null; String formTitle = null; String formBody = null; boolean formLocation = false; private boolean sign = true; private String customSign = null; private boolean signModel = false; /* Location listener */ private boolean locationEnabled = false; private Location currentLocation = null; LocationListener locationTracker = new LocationListener() { public void onLocationChanged(Location location) { currentLocation = location; ((Button) findViewById(R.id.upload_ok)).setEnabled(true); findViewById(R.id.upload_location_progress).setVisibility(View.INVISIBLE); } public void onProviderDisabled(String provider) { } public void onProviderEnabled(String provider) { } public void onStatusChanged(String provider, int status, Bundle extras) { } }; /* when pressed 'OK' button */ OnClickListener proceedHandler = new OnClickListener() { public void onClick(View v) { Application app = (Application) getApplication(); EditText title, contents; title = (EditText) findViewById(R.id.upload_title); contents = (EditText) findViewById(R.id.upload_text); DialogInterface.OnClickListener simpleCloser = new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }; if (target == null) { ((EditText) findViewById(R.id.upload_target)).setText(""); new AlertDialog.Builder(ActivityUploader.this).setTitle("") .setMessage(" ? .").setNeutralButton("?", simpleCloser) .show(); return; } if (title.getText().length() == 0 || contents.getText().length() == 0) { new AlertDialog.Builder(ActivityUploader.this).setTitle("") .setMessage("? .").setNeutralButton("?", simpleCloser) .show(); return; } if (!app.isSignedOn()) { startActivityForResult(new Intent(ActivityUploader.this, ActivitySignOn.class), Application.ACTION_SIGN_ON); } else { publish(); } } }; /* class for binding image data into the image view */ private class ImageUriAdapter extends BaseAdapter { private int gallery_background; public ImageUriAdapter() { TypedArray a = obtainStyledAttributes(R.styleable.default_gallery); gallery_background = a.getResourceId(R.styleable.default_gallery_android_galleryItemBackground, 0); } public int getCount() { return contents.size(); } public Object getItem(int position) { return contents.get(position); } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { ImageView iv = new ImageView(ActivityUploader.this); iv.setImageBitmap(bitmaps.get(position)); iv.setAdjustViewBounds(true); iv.setBackgroundResource(gallery_background); return iv; } }; private int queryOrientation(Uri uri) { Log.d(Application.TAG, "querying " + uri.toString()); ContentResolver cr = ActivityUploader.this.getContentResolver(); int orientation = 0; Cursor c = cr.query(uri, new String[] { MediaStore.Images.ImageColumns.ORIENTATION, }, null, null, null); if (c != null) { c.moveToFirst(); orientation = c.getInt(0); c.close(); return orientation; } /* If there's no such item in ContentResolver, query EXIF */ return queryExifOrientation(uri.getPath()); } static private Constructor<?> exifConstructor = null; static private Method exifGetAttributeInt = null; public int queryExifOrientation(String path) { int orientation = 0; if (exifConstructor == null) { try { exifConstructor = ExifInterface.class.getConstructor(new Class[] { String.class }); exifGetAttributeInt = ExifInterface.class.getMethod("getAttributeInt", new Class[] { String.class, int.class }); } catch (NoSuchMethodException e) { return 0; } } Integer o = 0; try { Object obj = exifConstructor.newInstance(new Object[] { path }); o = (Integer) exifGetAttributeInt.invoke(obj, ExifInterface.TAG_ORIENTATION, new Integer(0)); } catch (Exception e) { return 0; } Log.d(Application.TAG, "orientation " + o); switch (o) { case ExifInterface.ORIENTATION_ROTATE_90: orientation = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: orientation = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: orientation = 270; } return orientation; } private Bitmap getBitmapThumbnail(Uri uri) { Bitmap b = null; try { b = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri)); } catch (FileNotFoundException e1) { try { b = BitmapFactory.decodeStream(new FileInputStream(uri.getPath())); } catch (FileNotFoundException e2) { return Bitmap.createBitmap(64, 64, Bitmap.Config.ARGB_4444); } } int orientation = queryOrientation(uri); Bitmap resized = BitmapHelper.getResizedBitmap(b, 64, BitmapHelper.Axis.Vertical, orientation); b.recycle(); return resized; } private void reloadConfigurations() { SharedPreferences pref = getSharedPreferences(Application.APP, Activity.MODE_PRIVATE); maximumResolution = pref.getInt(ActivityPreferences.KEY_MAXIMUM_RESOLUTION, ActivityPreferences.DEFAULT_MAXIMUM_RESOLUTION); imageQuality = pref.getInt(ActivityPreferences.KEY_IMAGE_QUALITY, ActivityPreferences.DEFAULT_IMAGE_QUALITY); sizeThreshold = pref.getInt(ActivityPreferences.KEY_IMAGE_RESIZE_THRESHOLD, ActivityPreferences.DEFAULT_IMAGE_RESIZE_THRESHOLD); mobilePageProvider = pref.getString(ActivityPreferences.KEY_MOBILE_PAGE_PROVIDER, ActivityPreferences.DEFAULT_MOBILE_PAGE_PROVIDER); pageDestination = pref.getString(ActivityPreferences.KEY_DESTINATION, ActivityPreferences.DEFAULT_DESTINATION); formLocation = pref.getBoolean(ActivityPreferences.KEY_ALWAYS_ENCLOSE_POSITION, ActivityPreferences.DEFAULT_ALWAYS_ENCLOSE_POSITION); sign = pref.getBoolean(ActivityPreferences.KEY_SIGNATURE, ActivityPreferences.DEFAULT_SIGNATURE); boolean use_custom_signature = pref.getBoolean(ActivityPreferences.KEY_USE_CUSTOM_SIGNATURE, ActivityPreferences.DEFAULT_USE_CUSTOM_SIGNATURE); if (use_custom_signature) customSign = pref.getString(ActivityPreferences.KEY_CUSTOM_SIGNATURE, ""); signModel = pref.getBoolean(ActivityPreferences.KEY_ALWAYS_ENCLOSE_MODEL, ActivityPreferences.DEFAULT_ALWAYS_ENCLOSE_MODEL); ((CheckBox) findViewById(R.id.upload_enclose_position)).setChecked(formLocation); } private void resetThumbnails() { bitmaps.clear(); for (int i = 0; i < contents.size(); ++i) bitmaps.add(getBitmapThumbnail(contents.get(i))); } private void setDefaultImage() { if (galleryChanged || target == null) return; contents.clear(); bitmaps.clear(); DatabaseHelper db = new DatabaseHelper(this); String path = db.getImage(target); db.close(); if (path != null && path.length() > 0) contents.add(Uri.parse(path)); updateImageButtons(); resetThumbnails(); updateGallery(); } private void updateGallery() { Gallery g = (Gallery) findViewById(R.id.upload_images); ImageUriAdapter ua = new ImageUriAdapter(); g.setAdapter(ua); } private void updateImageButtons() { Button ba = (Button) findViewById(R.id.upload_photo_add); Button bd = (Button) findViewById(R.id.upload_photo_delete); Button bt = (Button) findViewById(R.id.upload_photo_take); if (contents.size() == 5) { bt.setEnabled(false); ba.setEnabled(false); bd.setEnabled(true); } else if (contents.size() == 0) { galleryChanged = false; bt.setEnabled(true); ba.setEnabled(true); bd.setEnabled(false); } else { bt.setEnabled(true); ba.setEnabled(true); bd.setEnabled(true); } } Runnable onSuccess = new Runnable() { public void run() { Intent i = new Intent(ActivityUploader.this, ActivityResult.class); i.putExtra("target", target); i.putExtra("no", targetNo); i.putExtra("called", called); i.putExtra("destination", destination); finish(); startActivity(i); } }; Runnable reSignOn = new Runnable() { public void run() { startActivityForResult(new Intent(ActivityUploader.this, ActivitySignOn.class), Application.ACTION_SIGN_ON); } }; Handler signOffResultHandler = new Handler() { @Override public void handleMessage(Message m) { signOffProgressDialog.stop(); if (m.getData().getBoolean("result")) { Application app = (Application) getApplication(); app.setSignedOn(false, app.authenticationMethod()); } } }; /* * Uploader procedure */ Runnable publisherThread = new Runnable() { private void uploadImages(MultipartEntity flout) throws TemporarilyUnavailable, PageError { if (contents.size() == 0) return; HttpPost post = new HttpPost(UPLOAD_IMAGE_URL); MultipartEntity entity = new MultipartEntity(); ContentResolver cr = ActivityUploader.this.getContentResolver(); Application app = (Application) getApplication(); try { entity.addPart("imgId", new StringBody(target, Charset.forName("utf-8"))); entity.addPart("mode", new StringBody("write", Charset.forName("utf-8"))); } catch (Exception e) { } ArrayList<InputStream> streams = new ArrayList<InputStream>(); int cnt = 0; for (Uri uri : contents) { boolean localfile = false; if (uri.getScheme().equals("file")) localfile = true; int size = 0; String mime = "image/jpeg"; int orientation = 0; String filename = ""; boolean nodata = false; if (!localfile) { Cursor c = cr.query(uri, new String[] { MediaStore.Images.ImageColumns.SIZE, MediaStore.Images.ImageColumns.MIME_TYPE, MediaStore.Images.ImageColumns.ORIENTATION, MediaStore.MediaColumns.DISPLAY_NAME }, null, null, null); if (c != null) { c.moveToFirst(); size = c.getInt(0); mime = c.getString(1); orientation = c.getInt(2); filename = c.getString(3); c.close(); } else { Log.d(Application.TAG, "file " + uri.toString() + " not found."); nodata = true; } } /* not in contentprovider database */ if (localfile || nodata) { size = (int) new File(uri.getPath()).length(); orientation = queryOrientation(uri); filename = uri.getLastPathSegment(); String lfn = filename.toLowerCase(); if (lfn.endsWith(".jpg") || lfn.endsWith(".jpeg")) mime = "image/jpeg"; else if (lfn.endsWith(".png")) mime = "image/png"; else if (lfn.endsWith(".gif")) mime = "image/gif"; else if (lfn.endsWith(".bmp")) mime = "image/bmp"; else mime = "image/jpeg"; // presume } String lfn = filename.toLowerCase(); if (mime.equals("image/jpeg")) { if (!lfn.endsWith(".jpg") && !lfn.endsWith(".jpeg")) filename += ".jpg"; } else if (mime.equals("image/png")) { if (!lfn.endsWith(".png")) filename += ".png"; } else if (mime.equals("image/gif")) { if (!lfn.endsWith(".gif")) filename += ".gif"; } else { if (!filename.contains(".")) filename += ".jpg"; // presume } InputStream is; if (size > sizeThreshold || orientation != 0) { /* convert image file */ Log.d(Application.TAG, "image " + filename + " needs to be converted."); try { File f = File.createTempFile("dcuploader_resize", ".jpg"); String path = f.getAbsolutePath(); tempFiles.add(path); mime = "image/jpeg"; FileOutputStream fo = new FileOutputStream(f); Bitmap o = BitmapFactory.decodeStream(cr.openInputStream(uri)); Bitmap b = BitmapHelper.getResizedBitmapConstrained(o, maximumResolution, orientation); b.compress(CompressFormat.JPEG, imageQuality, fo); o.recycle(); b.recycle(); fo.close(); is = new FileInputStream(path); } catch (Exception e) { e.printStackTrace(); continue; } } else { try { is = cr.openInputStream(uri); } catch (FileNotFoundException e) { Log.d(Application.TAG, "file not found: " + uri.toString()); e.printStackTrace(); continue; } } streams.add(is); try { entity.addPart("file_txt" + (cnt + 1), new StringBody(filename, Charset.defaultCharset())); } catch (Exception e) { } /* this is not going to happen */ entity.addPart("upload[" + cnt + "]", new InputStreamBody(is, mime, filename)); Log.d(Application.TAG, "Image " + filename + " added."); ++cnt; } post.setEntity(entity); post.setHeader("Referer", FORM_URL + "?id=" + target); post.setHeader("Origin", GALL_URL); HttpResponse resp; try { resp = app.sendPostRequest(post); /* clean up all the mess */ for (InputStream is : streams) is.close(); for (String path : tempFiles) new File(path).delete(); tempFiles.clear(); } catch (SocketTimeoutException e) { throw new TemporarilyUnavailable(); } catch (Exception e) { uploadProgressDialog.error(e.toString()); return; } HttpEntity resultEntity = resp.getEntity(); BufferedReader r; try { r = new BufferedReader(new InputStreamReader(resultEntity.getContent(), "UTF-8")); } catch (Exception e) { e.printStackTrace(); uploadProgressDialog.error(e.toString()); return; } String fldata = ""; String ofldata = ""; while (true) { String line; try { line = r.readLine(); } catch (IOException e) { e.printStackTrace(); throw new PageError(e.toString()); } if (line == null) break; if (line.contains("\"FL_DATA\"")) { fldata = line.substring(line.indexOf('\'')).replace("'", "").replace(";", "").trim(); } else if (line.contains("\"OFL_DATA\"")) { ofldata = line.substring(line.indexOf('\'')).replace("'", "").replace(";", "").trim(); } } Log.d(Application.TAG, "Images uploaded successfully."); try { flout.addPart("FL_DATA", new StringBody(fldata, Charset.defaultCharset())); flout.addPart("OFL_DATA", new StringBody(ofldata, Charset.defaultCharset())); String rot = "0"; for (int i = 1; i < cnt; ++i) rot += ";" + i; flout.addPart("rot", new StringBody(rot, Charset.defaultCharset())); } catch (UnsupportedEncodingException e) { } } private void fetchFormPage(MultipartEntity mpentity) throws Exception { Application app = (Application) getApplication(); HttpGet req; HttpResponse resp; HttpEntity entity; BufferedReader r; /* Get POST variables */ req = new HttpGet(FORM_URL + "?id=" + target); try { resp = ((Application) getApplication()).sendGetRequest(req); } catch (SocketTimeoutException e) { throw new TemporarilyUnavailable(); } catch (Exception e) { e.printStackTrace(); uploadProgressDialog.error(e.toString()); throw e; } entity = resp.getEntity(); try { r = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8")); } catch (Exception e) { e.printStackTrace(); uploadProgressDialog.error(e.toString()); throw e; } boolean errorFlag = false; boolean gettingErrorStr = false; String errorMsg = ""; while (true) { String line; try { line = r.readLine(); } catch (IOException e) { throw new TemporarilyUnavailable(); } if (line == null) break; String key, value; if (line.contains(LOGIN_STATUS_URL)) { if (line.contains("&chk=N") && app.authenticationMethod() == Application.AUTHENTICATION_METHOD_GALLOG) throw new TimedOut(); } else if (line.contains(AGE_VERIFICATION_URL)) { if (app.authenticationMethod() == Application.AUTHENTICATION_METHOD_GALLOG) throw new TimedOut(); else throw new AgeVerificationNeeded(); } else if (line.contains("? ")) { throw new NoPermission(); } else if (line.contains("<input type=hidden")) { Pattern p; Matcher m; p = Pattern.compile("name=([\"_a-zA-Z0-9]+)"); m = p.matcher(line); m.find(); key = m.group(1).replace("\"", "").trim(); /* we're going to add those later */ if (key.equals("FL_DATA") || key.equals("OFL_DATA") || key.equals("rot") || key.equals("check_attack")) continue; p = Pattern.compile("value=([\"_a-zA-Z0-9]+)"); try { m = p.matcher(line); m.find(); value = m.group(1).replace("\"", "").trim(); } catch (IllegalStateException e) { value = ""; } try { mpentity.addPart(key, new StringBody(value, Charset.forName("utf-8"))); } catch (Exception e) { } } else if (line.contains("Message")) { Log.d(Application.TAG, "Unexpected error."); errorFlag = true; gettingErrorStr = true; } else if (gettingErrorStr) { if (line.contains("Move Back")) { gettingErrorStr = false; } else { String stripped = line.replaceAll("\\<.*?>", "").trim(); if (stripped.length() > 0) errorMsg += stripped + "\n"; } } } if (errorFlag) { throw new PageError(errorMsg); } try { entity.consumeContent(); } catch (IOException e) { } } public void run() { MultipartEntity entity = new MultipartEntity(); try { fetchFormPage(entity); uploadImages(entity); } catch (TimedOut e) { Application app = (Application) getApplication(); app.setSignedOn(false, app.authenticationMethod()); uploadProgressDialog.stop(); new Handler().post(reSignOn); return; } catch (AgeVerificationNeeded e) { uploadProgressDialog.error("??? ."); return; } catch (NoPermission e) { uploadProgressDialog.error("? ? ."); return; } catch (TemporarilyUnavailable e) { uploadProgressDialog.error("? ? ."); return; } catch (PageError e) { uploadProgressDialog.error(e.toString()); return; } catch (Exception e) { return; } EditText subject = (EditText) findViewById(R.id.upload_title); EditText contents = (EditText) findViewById(R.id.upload_text); String cstr = contents.getText().toString().trim().replace("<", "<").replace(">", ">") .replace("\n", "<br />"); String postfix_; if (sign) { postfix_ = "<br /><br />"; if (customSign != null) postfix_ += customSign; else postfix_ += postfix; if (signModel) postfix_ += STAMP_MODEL; } else { postfix_ = ""; } try { entity.addPart("subject", new StringBody(subject.getText().toString(), Charset.forName("utf-8"))); entity.addPart("memo", new StringBody(cstr + mapstring + postfix_, Charset.forName("utf-8"))); } catch (Exception e) { } HttpPost post = new HttpPost(UPLOAD_URL); post.setHeader("Origin", GALL_URL); post.setHeader("Referer", FORM_URL + "?id=" + target); post.setEntity(entity); Log.d(Application.TAG, "Publishing article..."); Application app = (Application) getApplication(); HttpResponse resp; try { resp = app.sendPostRequest(post); } catch (Exception e) { uploadProgressDialog.error(e.toString()); return; } HttpEntity rentity = resp.getEntity(); BufferedReader r; try { r = new BufferedReader(new InputStreamReader(rentity.getContent(), "UTF-8")); } catch (Exception e) { e.printStackTrace(); uploadProgressDialog.error(e.toString()); return; } boolean errorFlag = false; boolean gettingErrorStr = false; String errorMsg = ""; while (true) { String line; try { line = r.readLine(); } catch (IOException e) { e.printStackTrace(); uploadProgressDialog.error(e.toString()); return; } if (line == null) break; Log.d(Application.TAG, line); if (line.contains("Message")) { errorFlag = true; gettingErrorStr = true; } else if (gettingErrorStr) { if (line.contains("Move Page")) { gettingErrorStr = false; } else { String stripped = line.replaceAll("\\<.*?>", "").trim(); if (stripped.length() > 0) errorMsg += stripped + "\n"; } } else if (line.contains("http-equiv=\"refresh\"")) { Pattern p = Pattern.compile("no=([0-9]+)"); Matcher m = p.matcher(line); if (!m.find()) { uploadProgressDialog .error(" ? ? ? ? ."); return; } targetNo = Integer.parseInt(m.group(1)); } } if (errorFlag) { uploadProgressDialog.error(errorMsg); return; } DatabaseHelper db = new DatabaseHelper(ActivityUploader.this); db.incrementHit(target); db.close(); new Handler().post(onSuccess); uploadProgressDialog.stop(); } }; /* publish your form */ private void publish() { /* include location info */ if (locationEnabled && currentLocation != null) { double latitude = currentLocation.getLatitude(); double longitude = currentLocation.getLongitude(); mapstring = "<br /><br /><img src='http://maps.google.com/maps/api/staticmap?center=" + latitude + "," + longitude + "&zoom=12&size=300x140&maptype=roadmap&markers=color:blue|label:|" + latitude + "," + longitude + "&markers=color:green&sensor=false' />"; } uploadProgressDialog.start(); new Handler() { @Override public void handleMessage(Message m) { new LooperDelegate(publisherThread).start(); } }.sendEmptyMessage(0); } private void initViews() { WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); if (wm.getDefaultDisplay().getOrientation() == 0) setContentView(R.layout.upload_portrait); else setContentView(R.layout.upload_landscape); EditText uploadTarget = (EditText) findViewById(R.id.upload_target); EditText uploadTitle = (EditText) findViewById(R.id.upload_title); EditText uploadText = (EditText) findViewById(R.id.upload_text); Button uploadVisit = (Button) findViewById(R.id.upload_visit); Button uploadPhotoTake = (Button) findViewById(R.id.upload_photo_take); Button uploadPhotoAdd = (Button) findViewById(R.id.upload_photo_add); Button uploadPhotoDelete = (Button) findViewById(R.id.upload_photo_delete); CheckBox uploadEnclosePosition = (CheckBox) findViewById(R.id.upload_enclose_position); Button uploadOk = (Button) findViewById(R.id.upload_ok); Button uploadCancel = (Button) findViewById(R.id.upload_cancel); /* set button behavior */ if (passThrough) uploadTarget.setClickable(false); else { uploadTarget.setClickable(true); registerForContextMenu(uploadTarget); } uploadTarget.setOnClickListener(new OnClickListener() { public void onClick(View v) { if (!passThrough) openContextMenu(v); } }); registerForContextMenu(uploadVisit); uploadVisit.setOnClickListener(new OnClickListener() { public void onClick(View v) { openContextMenu(v); } }); uploadPhotoTake.setOnClickListener(new OnClickListener() { public void onClick(View v) { try { tempFile = File.createTempFile("dcuploader_photo_", ".jpg"); } catch (IOException e) { Toast.makeText(ActivityUploader.this, " ?? .", Toast.LENGTH_SHORT).show(); tempFile = null; return; } Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (tempFile != null) i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile)); startActivityForResult(i, Application.ACTION_TAKE_PHOTO); } }); uploadPhotoAdd.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.setType("image/*"); i.addCategory(Intent.CATEGORY_DEFAULT); startActivityForResult(i, Application.ACTION_ADD_PHOTO); } }); uploadPhotoDelete.setOnClickListener(new OnClickListener() { public void onClick(View v) { Gallery g = (Gallery) findViewById(R.id.upload_images); int pos = g.getSelectedItemPosition(); if (pos == -1) return; contents.remove(pos); bitmaps.remove(pos); updateGallery(); updateImageButtons(); if (contents.size() == 0) pos = -1; else if (pos >= contents.size()) --pos; g.setSelection(pos); } }); uploadOk.setOnClickListener(proceedHandler); uploadCancel.setOnClickListener(new OnClickListener() { public void onClick(View v) { finish(); } }); uploadEnclosePosition.setChecked(formLocation); uploadEnclosePosition.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { locationEnabled = isChecked; queryLocation(isChecked); } }); /* restore data when orientation changes */ if (formGallery != null) { if (target != null) { uploadTarget.setText(formGallery); formGallery = null; } } if (formTitle != null) { uploadTitle.setText(formTitle); formTitle = null; } if (formBody != null) { uploadText.setText(formBody); formBody = null; } updateImageButtons(); updateGallery(); } private void queryLocation(boolean enabled) { LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); if (enabled) { lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationTracker); lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationTracker); ((Button) findViewById(R.id.upload_ok)).setEnabled(false); findViewById(R.id.upload_location_progress).setVisibility(View.VISIBLE); } else { lm.removeUpdates(locationTracker); ((Button) findViewById(R.id.upload_ok)).setEnabled(true); findViewById(R.id.upload_location_progress).setVisibility(View.INVISIBLE); } } private void visitPage(int id) { Uri uri; String queryString = "?id=" + target; if (id == MENU_DCINSIDE) uri = Uri.parse(Application.URL_LIST_DCINSIDE + queryString); else { if (mobilePageProvider.equals("moolzo")) uri = Uri.parse(Application.URL_LIST_MOOLZO + queryString); else uri = Uri.parse(Application.URL_LIST_DCMYS + queryString); } startActivity(new Intent(Intent.ACTION_VIEW, uri)); } private void resolveTarget(String id) { target = id; DatabaseHelper db = new DatabaseHelper(this); String title = db.getTitle(id); db.close(); if (title.length() > 0) ((EditText) findViewById(R.id.upload_target)).setText(title + " (" + id + ")"); else ((EditText) findViewById(R.id.upload_target)).setText(target); } /* * UI definition */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (tempFile != null) outState.putString("tempfile", tempFile.getAbsolutePath()); if (target != null) outState.putString("target", target); if (tempFiles.size() > 0) outState.putStringArrayList("tempfiles", tempFiles); if (contents.size() > 0) { String[] carr = new String[contents.size()]; int t = 0; for (Uri u : contents) carr[t++] = u.toString(); outState.putStringArray("contents", carr); } } @SuppressWarnings("unchecked") @Override public void onCreate(Bundle savedState) { super.onCreate(savedState); initViews(); if (formLocation) queryLocation(true); if (savedState != null) { if (savedState.containsKey("tempfile")) tempFile = new File(savedState.getString("tempfile")); if (savedState.containsKey("target")) resolveTarget(savedState.getString("target")); if (savedState.containsKey("tempfiles")) tempFiles = savedState.getStringArrayList("tempfiles"); if (savedState.containsKey("contents")) { contents = new ArrayList<Uri>(); String[] carr = savedState.getStringArray("contents"); for (String s : carr) contents.add(Uri.parse(s)); } } postfix = "from <a href=\"http://palladium.planetmono.org/dcuploader\">DCUploader</a>"; Button uploadVisit = (Button) findViewById(R.id.upload_visit); if (passThrough || target == null) uploadVisit.setEnabled(false); else uploadVisit.setEnabled(true); /* populate data by getting STREAM parameter */ Intent i = getIntent(); Bundle b = i.getExtras(); String action = i.getAction(); if (action.equals(Intent.ACTION_SEND) || action.equals(Intent.ACTION_SEND_MULTIPLE)) { called = true; if (i.hasExtra(Intent.EXTRA_STREAM)) { Object o = b.get(Intent.EXTRA_STREAM); /* quick and dirty. any better idea? */ try { contents.add((Uri) o); } catch (Exception e1) { try { contents = (ArrayList<Uri>) ((ArrayList<Uri>) o).clone(); } catch (Exception e2) { } } boolean exceeded = false; if (contents.size() > 5) { exceeded = true; do { contents.remove(5); } while (contents.size() > 5); } galleryChanged = true; updateImageButtons(); resetThumbnails(); updateGallery(); if (exceeded) Toast.makeText(this, " 5 . 5 ??? ? ?.", Toast.LENGTH_LONG).show(); } if (i.hasExtra(Intent.EXTRA_TEXT)) { ((EditText) findViewById(R.id.upload_text)).setText(b.getString(Intent.EXTRA_TEXT)); } } else if (action.equals("share")) { called = true; /* HTC web browser uses non-standard intent */ ((EditText) findViewById(R.id.upload_text)).setText(b.getString(Intent.EXTRA_TITLE)); } else if (action.equals(Intent.ACTION_VIEW)) { Uri uri = i.getData(); if (i.getCategories().contains(Intent.CATEGORY_BROWSABLE)) { passThrough = true; Pattern p = Pattern.compile("id=([\\-a-zA-Z0-9_]+)"); Matcher m = p.matcher(uri.toString()); if (m.find()) { resolveTarget(m.group(1)); } else { passThrough = false; } if (uri.getHost().equals(Application.HOST_DCMYS)) { destination = Application.DESTINATION_DCMYS; postfix = "from dc.m.dcmys.kr w/ <a href=\"http://palladium.planetmono.org/dcuploader\">DCUploader</a>"; } else if (uri.getHost().equals(Application.HOST_MOOLZO)) { destination = Application.DESTINATION_MOOLZO; postfix = "- From m.oolzo.com w/ <a href=\"http://palladium.planetmono.org/dcuploader\">DCUploader</a>"; } else if (uri.getHost().equals(Application.HOST_DCINSIDE)) { destination = Application.DESTINATION_DCINSIDE; } setDefaultImage(); } } reloadConfigurations(); } @Override public void onDestroy() { super.onDestroy(); Log.d(Application.TAG, "stopping activity."); /* stop location query when going out */ if (locationEnabled) { LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); lm.removeUpdates(locationTracker); } for (String path : tempFiles) new File(path).delete(); tempFiles.clear(); } @Override public void onResume() { super.onResume(); /* resume location query */ if (locationEnabled) { LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationTracker); lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationTracker); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK) { if (requestCode == Application.ACTION_ADD_PHOTO || requestCode == Application.ACTION_TAKE_PHOTO) { /* add photo */ if (contents.size() == 5) return; Uri selectedImage; Bitmap tbm; if (requestCode == Application.ACTION_ADD_PHOTO) { selectedImage = data.getData(); tbm = getBitmapThumbnail(selectedImage); } /*else if (requestCode == Application.ACTION_TAKE_PHOTO && data != null && data.hasExtra("data")) { Bundle b = data.getExtras(); String mpath = null; Bitmap bitmap = (Bitmap) b.get("data"); try { if (tempFile == null) { File f = File.createTempFile("dcuploader_photo_", ".jpg", Environment .getDownloadCacheDirectory()); FileOutputStream fo = new FileOutputStream(f); mpath = f.getAbsolutePath(); bitmap.compress(CompressFormat.JPEG, 90, fo); fo.close(); } else { mpath = tempFile.getAbsolutePath(); tempFile = null; } } catch (IOException e) { e.printStackTrace(); return; } selectedImage = Uri.parse("file://" + mpath); tempFiles.add(mpath); tbm = getBitmapThumbnail(bitmap); bitmap.recycle(); } */else { /* take photo */ selectedImage = Uri.fromFile(tempFile); tempFiles.add(tempFile.getAbsolutePath()); tbm = getBitmapThumbnail(selectedImage); } Gallery g = (Gallery) findViewById(R.id.upload_images); int npos = 0; int pos = g.getSelectedItemPosition(); if (pos == -1 || pos == 3) { contents.add(selectedImage); bitmaps.add(tbm); if (pos == 3) npos = pos + 1; } else { contents.add(pos + 1, selectedImage); bitmaps.add(pos + 1, tbm); npos = pos + 1; } updateGallery(); updateImageButtons(); g.setSelection(npos); galleryChanged = true; } else if (requestCode == Application.ACTION_ADD_GALLERY) { /* add gallery */ DatabaseHelper db = new DatabaseHelper(ActivityUploader.this); db.setFavorites(data.getStringArrayExtra("result")); db.close(); openContextMenu(findViewById(R.id.upload_target)); } else if (requestCode == Application.ACTION_SIGN_ON) { /* when signed on, go on. */ publish(); } else if (requestCode == Application.ACTION_PREFERENCES) { /* apply preferences */ Log.d(Application.TAG, "reloading configuration..."); reloadConfigurations(); setDefaultImage(); queryLocation(formLocation); } } } private ArrayList<String> ids = new ArrayList<String>(); private ArrayList<String> names = new ArrayList<String>(); @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); if (v.getId() == R.id.upload_target) { if (passThrough) return; menu.clear(); DatabaseHelper db = new DatabaseHelper(ActivityUploader.this); db.getFavorites(ids, names); db.close(); menu.setHeaderTitle(" ?"); for (int i = 0; i < names.size(); ++i) menu.add(MENU_GROUP_SELECT_GALLERY, i, 0, names.get(i)); menu.add(MENU_GROUP_SELECT_GALLERY, MENU_ADD_GALLERY, 0, " ..."); } else if (v.getId() == R.id.upload_visit) { menu.clear(); if (pageDestination.equals("dcinside")) { visitPage(MENU_DCINSIDE); } else if (pageDestination.equals("mobile")) { visitPage(MENU_MOBILE); } else { menu.setHeaderTitle(" ?"); String dest; if (mobilePageProvider.equals("moolzo")) dest = ""; else dest = "DCmys"; menu.add(MENU_GROUP_VISIT, MENU_DCINSIDE, 0, "??"); menu.add(MENU_GROUP_VISIT, MENU_MOBILE, 0, dest); } } } @Override public boolean onContextItemSelected(MenuItem item) { int id = item.getItemId(); int group = item.getGroupId(); if (group == MENU_GROUP_SELECT_GALLERY) { switch (id) { case MENU_ADD_GALLERY: startActivityForResult(new Intent(this, ActivityGalleryChooser.class), Application.ACTION_ADD_GALLERY); return true; default: resolveTarget(ids.get(id)); setDefaultImage(); if (!passThrough) ((Button) findViewById(R.id.upload_visit)).setEnabled(true); return true; } } else if (group == MENU_GROUP_VISIT) { visitPage(id); return true; } return true; } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater mi = getMenuInflater(); mi.inflate(R.menu.uploader, menu); Application app = (Application) getApplication(); if (!app.isSignedOn()) menu.findItem(R.id.menu_uploader_sign_off).setEnabled(false); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_uploader_preferences: Intent i = new Intent(ActivityUploader.this, ActivityPreferences.class); startActivityForResult(i, Application.ACTION_PREFERENCES); return true; case R.id.menu_uploader_sign_off: SignOnBase sob = new SignOnGallog(); /* TODO: subject to change */ Application app = (Application) getApplication(); signOffProgressDialog.start(); new Thread(sob.getMethodSignOff(app, signOffResultHandler)).start(); return true; default: return super.onOptionsItemSelected(item); } } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE || newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { formGallery = ((EditText) findViewById(R.id.upload_target)).getText().toString(); formTitle = ((EditText) findViewById(R.id.upload_title)).getText().toString(); formBody = ((EditText) findViewById(R.id.upload_text)).getText().toString(); formLocation = ((CheckBox) findViewById(R.id.upload_enclose_position)).isChecked(); initViews(); } } }