package nliveroid.nlr.main;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import nliveroid.nlr.main.parser.GateParser;
import nliveroid.nlr.main.parser.XMLparser;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Rect;
import android.net.Uri;
import android.os.AsyncTask;
import android.text.ClipboardManager;
import android.text.Layout;
import android.text.Spannable;
import android.text.Spannable.Factory;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
public class Gate {
private Gate Me;
private LiveInfo liveinfo;
private boolean isOpened;
private GestureDetector gestureDetector;
private int longPressVal;
private Factory factory;
// ドラッグ開始位置
int mOffsetDragStart = -1;
// ドラッグ終了位置g
int mOffsetDragEnd;
int mDragStartX;
int mDragStartY;
private boolean isFinished;
private String clipbordText;
private TextSelectArea title_text;
private TextSelectArea desc_text;
private boolean isSelectMode = false;// 長押しで選択モードにする
private int areaTouch = 0;
private TextSelectArea tag_text;
private TextSelectArea commu_text;
private Activity ACT;
private GateView gateView;
private ProgressBar p;
private String[] tagList;
private boolean ENDFLAG = true;
private TagArrangeDialog tagDialog;
private TweetDialog tweetDialog;
private String tweet_token;
protected Gate(final Activity act, final GateView gateView,
final LiveInfo liveObj,final boolean isOverLay,final String sessionid,String tweet_token) {
this(act,gateView,liveObj,isOverLay,sessionid);
this.tweet_token = tweet_token;
}
protected Gate(final Activity act, final GateView gateView,
final LiveInfo liveObj,final boolean isOveLay,final String sessionid) {
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," new Gate " + isOveLay);
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," new Gate " + act.getClass().getName());
Log.d("NLiveRoid","Gate startF " + liveObj.getLiveID() + " " + liveObj.getCommunity_info() + " " + liveObj.getCommunityName() + " " + liveObj.getCommunityID());
TopTabs.insertHis(1, liveObj.getLiveID(), liveObj.getCommunityID(), liveObj.getTitle(), liveObj.getCommunityName(), liveObj.getCommunity_info());
this.liveinfo = liveObj;
this.ACT = act;// error生成に使う
if(liveObj == null)return;//配信時になる
factory = Spannable.Factory.getInstance();
Me = this;
this.gateView = gateView;
gateView.clearViewStatus();
gestureDetector = new GestureDetector(ACT,new
OnGestureListener(){
@Override
public boolean onDown(MotionEvent arg0) {
return false;
}
@Override
public boolean onFling(MotionEvent arg0, MotionEvent arg1,
float arg2, float arg3) {
return false;
}
@Override
public void onLongPress(MotionEvent arg0) {
if(isSelectMode){
isSelectMode = false;
//コンテキストメニューを表示
switch(areaTouch){
case 0:
gateView.getTagLabel().setText("タグ 選択");
break;
case 1:
gateView.getTitleLabel().setText("放送タイトル 選択");
break;
case 2:
gateView.getDescLabel().setText("詳細 選択");
break;
case 3:
gateView.getCommuLabel().setText("コミュニティ情報 選択");
break;
}
}else{
isSelectMode= true;
gateView.getTagLabel().setText("タグ");
gateView.getTitleLabel().setText("タイトル");
gateView.getDescLabel().setText("詳細");
gateView.getCommuLabel().setText("コミュニティ情報");
}
}
@Override
public boolean onScroll(MotionEvent arg0, MotionEvent arg1,
float arg2, float arg3) {
return false;
}
@Override
public void onShowPress(MotionEvent arg0) {
}
@Override
public boolean onSingleTapUp(MotionEvent arg0) {
return false;
}
});
// サムネイル
if (liveObj.getThumbnail() != null) {
gateView.getCommuThumbView()
.setImageBitmap(liveObj.getThumbnail());
}else{
//サムネがnullだったらもう一度取得に行く
new ThumbNailTask().execute();
}
// タグ領域
tag_text = new TextSelectArea(ACT, gateView.getMainTable());
tag_text.setGravity(Gravity.LEFT);
tag_text.setPadding(20, 0, 20, 0);
tag_text.setWidth(gateView.getWidth() - 40);
((ViewGroup) gateView.getTagP()).addView(tag_text, -1, -2);
gateView.getTagP().setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// if(gestureDetector.onTouchEvent(arg1))return true;
if (!isSelectMode)
return gateView.getTagP().onTouchEvent(arg1);
int x = (int) (0.5 + arg1.getX());// 四捨五入
int y = (int) (0.5 + arg1.getY());
switch (arg1.getAction()) {
case MotionEvent.ACTION_DOWN:
isFinished = false;
mOffsetDragStart = tag_text.getOffset(x, y);
mDragStartX = x;
mDragStartY = y;
break;
case MotionEvent.ACTION_MOVE:
tag_text.updateDragSelection(x, y, false);
break;
case MotionEvent.ACTION_UP:
tag_text.updateDragSelection(x, y, true);
default: // キャンセル他
mOffsetDragStart = -1;
}
return true;
}
});
String tags = liveObj.getTags().replaceAll("\n", "");
if (tags != null && !tags.equals("")) {
NLiveRoid app = ((NLiveRoid) ACT.getApplicationContext());
HashMap<String, String> map = app.getTagNameMap();
String[] tagArray = tags.split("<<TAGXXX>>");
tagList = new String[tagArray.length - 1];// splitで最初のタグは無効
String result = "";
String temp = "";
if (map != null) {
for (int i = 1; i < tagArray.length; i++) {
// Log.d("log", "TAGARRAY I" + tagArray[i]);
temp = map.get(tagArray[i]);
if (temp != null) {
tagList[i - 1] = temp;
result += temp + " ";
}
}
tag_text.setText(result);
}
} else {
tag_text.setText(URLEnum.HYPHEN);
}
// タイトル領域
title_text = new TextSelectArea(ACT, gateView.getMainTable());
title_text.setGravity(Gravity.LEFT);
title_text.setPadding(20, 0, 20, 0);
title_text.setTextSize(20);
title_text.setWidth(gateView.getWidth() - 40);
((ViewGroup) gateView.getTitleP()).addView(title_text, -1, -2);
gateView.getTitleP().setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// if(gestureDetector.onTouchEvent(arg1))return true;
if (!isSelectMode)
return gateView.getTitleP().onTouchEvent(arg1);
int x = (int) (0.5 + arg1.getX());// 四捨五入
int y = (int) (0.5 + arg1.getY());
switch (arg1.getAction()) {
case MotionEvent.ACTION_DOWN:
isFinished = false;
mOffsetDragStart = title_text.getOffset(x, y);
mDragStartX = x;
mDragStartY = y;
break;
case MotionEvent.ACTION_MOVE:
title_text.updateDragSelection(x, y, false);
break;
case MotionEvent.ACTION_UP:
title_text.updateDragSelection(x, y, true);
default: // キャンセル他
mOffsetDragStart = -1;
}
return true;
}
});
String title = liveObj.getTitle();
if (title != null && !title.equals("")) {
title_text.setText(title);
} else {
title_text.setText(URLEnum.HYPHEN);
}
// 詳細領域
desc_text = new TextSelectArea(ACT, gateView.getMainTable());
desc_text.setGravity(Gravity.LEFT);
desc_text.setPadding(20, 0, 20, 0);
desc_text.setWidth(gateView.getWidth() - 40);
((ViewGroup) gateView.getDescP()).addView(desc_text, -1, -2);
gateView.getDescP().setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// if(gestureDetector.onTouchEvent(arg1)) return true;
if (!isSelectMode)
return gateView.getDescP().onTouchEvent(arg1);
int x = (int) (0.5 + arg1.getX());// 四捨五入
int y = (int) (0.5 + arg1.getY());
switch (arg1.getAction()) {
case MotionEvent.ACTION_DOWN:
isFinished = false;
mOffsetDragStart = desc_text.getOffset(x, y);
mDragStartX = x;
mDragStartY = y;
break;
case MotionEvent.ACTION_MOVE:
desc_text.updateDragSelection(x, y, false);
break;
case MotionEvent.ACTION_UP:
desc_text.updateDragSelection(x, y, true);
default: // キャンセル他
mOffsetDragStart = -1;
}
return true;
}
});
String descript = liveObj.getDescription();
if (descript != null && !descript.equals("")) {
desc_text.setText(descript
.replaceAll("<font.*?>|<u>|</u>|<b>|</b>|<i>|</i>|" +
"<s>|</s>|<a.*?>|</a>|<br>", ""));//なるべく消しておく
} else {
desc_text.setText(URLEnum.HYPHEN);
}
// コミュ情報テキスト領域
commu_text = new TextSelectArea(ACT, gateView.getMainTable());
commu_text.setGravity(Gravity.LEFT);
commu_text.setPadding(20, 0, 20, 0);
commu_text.setWidth(gateView.getWidth() - 40);
((ViewGroup) gateView.getCommuP()).addView(commu_text, -1, -2);
// gateView.getCommuP().setOnTouchListener(new OnTouchListener() {
// @Override
// public boolean onTouch(View arg0, MotionEvent arg1) {
// // if(gestureDetector.onTouchEvent(arg1)) return true;
// if (!isSelectMode)
// return gateView.getCommuP().onTouchEvent(arg1);
// int x = (int) (0.5 + arg1.getX());// 四捨五入
// int y = (int) (0.5 + arg1.getY());
// switch (arg1.getAction()) {
// case MotionEvent.ACTION_DOWN:
// isFinished = false;
// mOffsetDragStart = commu_text.getOffset(x, y);
// mDragStartX = x;
// mDragStartY = y;
// break;
// case MotionEvent.ACTION_MOVE:
// commu_text.updateDragSelection(x, y, false);
// break;
// case MotionEvent.ACTION_UP:
// commu_text.updateDragSelection(x, y, true);
// default: // キャンセル他
// mOffsetDragStart = -1;
// }
// return true;
// }
// });
String commu = liveObj.getCommunity_info();
if (commu != null && !commu.equals("")) {
commu_text.setText(commu.replaceAll("<font.*?>|<u>|</u>|<b>|</b>|<i>|</i>|" +
"<s>|</s>|<a.*?>|</a>|<br>", ""));//なるべく消しておく
} else {
commu_text.setText(URLEnum.HYPHEN);
}
// 来場者とコメント数
gateView.getViewCountView().setText(liveObj.getViewCount());
gateView.getResNumView().setText(liveObj.getResNumber());
gateView.getCloseView().setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
if (Me != null) {
Me.close();
}
return false;
}
});
// 開場、開演テキスト getplayerでUTCで返ってくる時と、GateのHH:mmの両方入ってくる
if(!(liveObj.isOwner()&&!liveObj.isLiveStarted())){//配信テスト中は時間がマイナスで計算しずら過ぎる
String starttime = liveObj.getStartTime();
//02/05(日)00:03開始 1328367797
// 経過時間
// Log.d("log","GATE Start Time --------------------- " + starttime);
try{
// long nowMills = System.currentTimeMillis();
// if(nowMills/1000 < Long.parseLong(starttime)){//配信開始前は未来の時間になってる
// gateView.getPassedTime().setText(URLEnum.HYPHEN);
Matcher smc = Pattern.compile("[0-9][0-9]:[0-9][0-9]").matcher(
starttime);
if(liveObj.getPassedTime().contains("<<SPLIT>>")){//ランキングだった(getRankingValueとかは何故か使いまわされるから使えない)
gateView.getPassedTime().setText(liveObj.getPassedTime(false).split("<<SPLIT>>")[1]+"分");
}else if (smc.find()) {//Gateだった
starttime = smc.group();
gateView.getStart().setText(starttime);
}else{
Matcher utc = Pattern.compile("[0-9]{10,15}").matcher(starttime);
if(utc.find()){//getPlayerだった
Date d = new Date(Long.parseLong(utc.group())*1000);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
starttime = sdf.format(d);
gateView.getStart().setText(starttime);
}
}
Date date = new Date();
SimpleDateFormat sdf1 = new SimpleDateFormat("HH:mm");
String[] startTime = starttime.split(":");
String[] nowTime = sdf1.format(date).split(":");
//1日以上続いている放送には対応しない
int start_hour = Integer.parseInt(startTime[0]);
int start_minutes = Integer.parseInt(startTime[1]);
int now_hour = Integer.parseInt(nowTime[0]);
int now_minutes = Integer.parseInt(nowTime[1]);
if(now_hour-start_hour < 0){//日付跨いでいた
now_hour+=24;
}
if(now_minutes-start_minutes < 0){
now_minutes+=60;
}
if(now_hour-start_hour > 0){
gateView.getPassedTime().setText(String.format("%d時間%d分", (now_hour-start_hour),(now_minutes-start_minutes)%60));
}else{
gateView.getPassedTime().setText(String.format("%d分", (now_minutes-start_minutes)%60));
}
}catch(Exception e){
//シカト
Log.d("NLiveRoid","Gate Time Failed");
}
}
//座席
String seetStr = liveObj.getRoomlabel() + "/" + liveObj.getRoomno() + "番";
gateView.getSeetText().setText(seetStr);
// 各ボタン--------------------------------------------------------------
gateView.getCopyB().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," getCopyB");
if(ENDFLAG){
MyToast.customToastShow(ACT, "放送情報取得が完了していません");
return;
}
new AlertDialog.Builder(ACT)
.setTitle("クリップボードにコピー")
.setItems(new String[]{"放送URL","コミュニティURL","タイトル","詳細","コミュ詳細"},
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int which) {
ClipboardManager cm = (ClipboardManager) ACT.getSystemService(ACT.CLIPBOARD_SERVICE);
// クリップボードへ値をコピー。
switch(which){
case 0:
cm.setText(URLEnum.PC_WATCHBASEURL + liveinfo.getLiveID());
break;
case 1:
if(liveinfo.getCommunityID().equals(URLEnum.HYPHEN)){
MyToast.customToastShow(ACT, "コミュニティタイトル取得できません");
return;
}
cm.setText(URLEnum.COMMUNITYURL + liveinfo.getCommunityID());
break;
case 2:
cm.setText(liveinfo.getTitle().replaceAll("<<LINK1>>" +
"|<font.*?>" +
"|</font>" +
"|<s/*?>" +
"|</s>" +
"|<i.*?>" +
"|</i>" +
"|<br>", ""));
break;
case 3:
cm.setText(liveinfo.getDescription().replaceAll("<<LINK1>>" +
"|<font.*?>" +
"|</font>" +
"|<s/*?>" +
"|</s>" +
"|<i.*?>" +
"|</i>" +
"|<br>", ""));
break;
case 4:
cm.setText(liveinfo.getCommunity_info().replaceAll("<<LINK1>>" +
"|<font.*?>" +
"|</font>" +
"|<s/*?>" +
"|</s>" +
"|<i.*?>" +
"|</i>" +
"|<br>", ""));
break;
}
}
}).create().show();
}
});
gateView.getCommunityLinkB().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if(NLiveRoid.isDebugMode){
Log.d("NLiveRoid"," getCommuLinkB" + liveinfo);
if(liveinfo != null){
if(liveinfo != null)Log.d("NLiveRoid"," " + liveinfo.getLiveID());
if(liveinfo != null)Log.d("NLiveRoid"," " + liveinfo.getCommunityID());
if(liveinfo != null)Log.d("NLiveRoid"," " + liveinfo.getDefaultCommunity());//初期化後に-からnullにセットされる事がある
}
}
if(liveinfo == null || liveinfo.getLiveID() == null || (liveinfo.getCommunityID().equals(URLEnum.HYPHEN)&&liveinfo.getDefaultCommunity() == null)||(liveinfo.getCommunityID().equals(URLEnum.HYPHEN ) &&liveinfo.getDefaultCommunity().equals(URLEnum.HYPHEN))){
MyToast.customToastShow(ACT, "コミュニティIDが取得できませんでした");
Log.d("NLiveRoid"," " + liveinfo);
if(liveinfo != null){
if(liveinfo != null)Log.d("NLiveRoid"," " + liveinfo.getLiveID());
if(liveinfo != null)Log.d("NLiveRoid"," " + liveinfo.getCommunityID());
if(liveinfo != null)Log.d("NLiveRoid"," " + liveinfo.getDefaultCommunity());
}
return;
}else if(liveinfo.getCommunityID().equals(URLEnum.HYPHEN) && liveinfo.getDefaultCommunity().matches("co[0-9]+")){
liveinfo.setCommunityID(liveinfo.getDefaultCommunity());//理由は忘れたが、getplayerでのdefaultCommunityのみでコミュIDを取ってきてる場合がある
}
if(!liveinfo.getCommunityID().matches("co[0-9]+")){
MyToast.customToastShow(ACT, "ユーザー放送が検出されませんでした");
return;
}
final AlertDialog.Builder dialog = new AlertDialog.Builder(ACT);
dialog
.setItems(new CharSequence[]{"参加/退会","最近の放送履歴"}, new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int which) {
switch(which){
case 0:
dialog.dismiss();
//コミュ参加/退会
new CommunityInfoTask(ACT,liveinfo.getCommunityID(),sessionid,gateView.getWidth()).execute();
break;
case 1://最近の放送履歴
NLiveRoid app = (NLiveRoid)ACT.getApplicationContext();
new LiveArchivesDialog((Archiver)ACT,liveinfo.getCommunityID(),app.getViewWidth(),app.getError()).showSelf();
break;
}
}
})
.create().show();
}
});
gateView.getBrowserLinkB().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," getSentenceLinkB");
if(liveinfo == null || liveinfo.getDescription() == null || liveinfo.getCommunity_info() == null){
return;
}
CharSequence[] items = null;
if(liveinfo.getCommunityID().matches("co[0-9]+")){//文中リンク、配信者ページは確実にできるので最初にしておく
items = new CharSequence[]{"詳細文中のリンク","配信者ページ","コミュニティページ","BBS","ブロマガ","オーナーページ"};
}else{
items = new CharSequence[]{"詳細文中のリンク"};
}
new AlertDialog.Builder(ACT)
.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Uri uri = null;//whichが2以上の時のみ
switch(which){
case 0://文中リンク
final String[] links;
String description = liveinfo.getDescription();
String commuinfo = liveinfo.getCommunity_info();
String allStr = description + commuinfo;
Pattern urlPt = Pattern.compile("(http|https):([^\\x00-\\x20()\"<>\\x7F-\\xFF])*", Pattern.CASE_INSENSITIVE);
Matcher mc0 = urlPt.matcher(allStr);
//co user mylist は普通にブラウザ連携としておく
Matcher mc1 = Pattern.compile("co[0-9]+").matcher(allStr);
Matcher mc2 = Pattern.compile("user/[0-9]+").matcher(allStr);
Matcher mc3 = Pattern.compile("mylist/[0-9]+").matcher(allStr);
//リンクを文字列的に取得しておく
ArrayList<String> linkList = new ArrayList<String>();
for(int i = 0; i < 30; i++){//アンカーとしてのリンクは30個まで
Matcher mcL = Pattern.compile("<<LINK"+i+">>.+<<LINK"+i+">>").matcher(allStr);
if(mcL.find()){
linkList.add(mcL.group().replaceAll("<<LINK[0-9]+?>>", ""));
}
}
if(mc0.find()){
do{
linkList.add(mc0.group());
}while(mc0.find());
}
if(mc1.find()){
do{
linkList.add(URLEnum.COMMUNITYURL+mc1.group());
}while(mc1.find());
}
if(mc2.find()){
do{
linkList.add("http://www.nicovideo.jp/"+mc2.group());
}while(mc2.find());
}
if(mc3.find()){
do{
linkList.add("http://www.nicovideo.jp/"+mc3.group());
}while(mc3.find());
}
links = new String[linkList.size()];
for(int i = 0; i <linkList.size() ;i++){
links[i] = linkList.get(i);
}
if(links.length ==0){
MyToast.customToastShow(ACT, "リンクが検出できませんでした");
return;
}
new AlertDialog.Builder(ACT)
.setTitle("リンク先へ")
.setItems(links,
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int which) {
if(NLiveRoid.isDebugMode)Log.d("log", "links "
+ links[which]);
Uri uri = null;
Random rand = new Random();
// //セッション編集
// String[] split_ = sessionid.split("_");
// for(String i:split_){
// Log.d("log", "session: "+i);
// }
uri = Uri.parse(links[which]);
if(NLiveRoid.isDebugMode)Log.d("Log","URI - " + uri.getPath());
Intent i = new Intent(Intent.ACTION_VIEW);
i.addCategory(Intent.CATEGORY_BROWSABLE);
i.setDataAndType(uri, "text/html");
ACT.startActivityForResult(i,CODE.RESULT_REDIRECT);//リダイレクトコード
}
}).show();
return;
case 1:
if(liveinfo.getOwnerID() == null){
new OwnerParseTask().execute(sessionid);
}else{
uri = Uri.parse(URLEnum.USERPAGE + liveinfo.getOwnerID());
Intent i = new Intent(Intent.ACTION_VIEW);
i.addCategory(Intent.CATEGORY_BROWSABLE);
i.setDataAndType(uri, "text/html");
ACT.startActivityForResult(i,CODE.RESULT_REDIRECT);//リダイレクトコード
}
return;
case 2:
uri = Uri.parse(URLEnum.COMMUNITYURL +liveinfo.getCommunityID());
break;
case 3:
uri = Uri.parse(URLEnum.BBS + liveinfo.getCommunityID());
break;
case 4:
new CommuBrowser(ACT, ((NLiveRoid)ACT.getApplicationContext()).getError(), new ProgressBar(ACT), 0,liveinfo.getCommunityID()).execute();
return;
case 5:
new CommuBrowser(ACT, ((NLiveRoid)ACT.getApplicationContext()).getError(), new ProgressBar(ACT), 1,liveinfo.getCommunityID()).execute();
return;
}
Intent i = new Intent(Intent.ACTION_VIEW);
i.addCategory(Intent.CATEGORY_BROWSABLE);
i.setDataAndType(uri, "text/html");
ACT.startActivityForResult(i,CODE.RESULT_REDIRECT);//リダイレクトコード
}
}).create().show();
}
});
//タグ検索/編集
gateView.getTagLnkB().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," getTagLnkB");
final AlertDialog.Builder dialog = new AlertDialog.Builder(ACT);
dialog.setItems(new String[]{"キーワード検索","編集"}, new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int which) {
switch(which){
case 0:
//検索
dialog.dismiss();
//検索ロジック
try{
if (tagList != null && tagList.length > 0) {
new AlertDialog.Builder(ACT)
.setTitle("キーワード検索")
.setItems(tagList,
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int which) {
Log.d("log", "TAG LSIT "
+ tagList[which]);
close_noanimation();
if(isOveLay){
if(ACT != null){
//視聴画面を終わる
if(OverLay.getOvarLay() != null){
OverLay.getOvarLay().finish(CODE.RESULT_FROM_GATE_FINISH);
}
}
}
//onActivityResultを直接呼ぶ
if (SearchTab.getSearchTab() == null ) {//別プロセスか、まだサーチタブを開いていない
if(TopTabs.getACT() == null){//TopTabsが別プロセス=Flash||BC
// Log.d("Gate","ANOTHER PROCESS -----");
//FlashPlayer||BCPlayerをonActtivityResultから終了→BackGroundServiceからサーチタブへ
if(TransDiscr.getACT() != null){
TransDiscr.getACT().forTagSearch(tagList[which]);
}else if(FlashPlayer.getACT() != null){//コメントのみ
Intent data = new Intent();
data.putExtra("init_mode", (byte)1);
data.putExtra("tagword", tagList[which]);
FlashPlayer.getACT().onActivityResult(CODE.RESULT_TRANS_LAYER,CODE.RESULT_TRANS_LAYER,data);
}else if(BCPlayer.getBCACT() != null){//コメントのみで配信?なし?
Intent data = new Intent();
data.putExtra("init_mode", (byte)1);
data.putExtra("tagword", tagList[which]);
BCPlayer.getBCACT().onActivityResult(CODE.RESULT_TRANS_LAYER,CODE.RESULT_TRANS_LAYER,data);
}
}else{//同一プロセス=OverLay
TopTabs.getACT().changeTag(1);
SearchTab.getSearchTab()
.keyWordSearch_FromGate(
tagList[which]);
}
}else{//SearchTabを開いたことがある
TopTabs.getACT().changeTag(1);
SearchTab.getSearchTab()
.keyWordSearch_FromGate(
tagList[which]);
}
}
}).show();
}
}catch(Exception e){
e.printStackTrace();
}
break;
case 1:
//編集ロジック
dialog.dismiss();
tagDialog = new TagArrangeDialog(ACT,sessionid,liveinfo.getLiveID(),gateView.getWidth());
tagDialog.show();
break;
}
}
})
.create().show();
}
});
gateView.snsLnkB().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," getSNSLnkB");
new AlertDialog.Builder(ACT)
.setItems(new CharSequence[]{"Tweet(NLR)","Tweet","mixiチェック","LINEで送る"}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Uri uri = null;
switch(which){
case 0:
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid","Tweet at gate app" );
if(tweet_token == null){
NLiveRoid app = (NLiveRoid)ACT.getApplicationContext();
tweet_token = app.getDefaultMap().get("twitter_token") + " " + app.getDefaultMap().get("twitter_secret");
}
if(tweet_token == null || tweet_token.split(" ").length < 2){
MyToast.customToastShow(ACT, "Twitter認証されていませんでした");
return;
}else{
tweetDialog = new TweetDialog(ACT, liveObj, tweet_token,false);
tweetDialog.showSelf();
}
return;
case 1:
uri = Uri.parse("http://mobile.twitter.com/?status="+liveinfo.getTitle() +" http://nico.ms/"+liveinfo.getLiveID() + " #"+liveinfo.getLiveID() + " #nicolive" );
break;
case 2:
uri = Uri.parse("http://mixi.jp/share.pl?u=http://live.nicovideo.jp/watch/"+liveinfo.getLiveID() +"&k=5319e6394c09374bb633820cb07add6a335076b2");
break;
case 3:
uri = Uri.parse("line://msg/text/?" + liveinfo.getTitle() + URLEnum.SP_WATCHBASEURL+liveinfo.getLiveID()+"?cp_webto=share");
break;
}
try{
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
ACT.startActivity(intent);
}catch(ActivityNotFoundException e){
e.printStackTrace();
MyToast.customToastShow(ACT, "起動できるアプリケーションが見つかりませんでした");
}catch(Exception e){
e.printStackTrace();
MyToast.customToastShow(ACT, "アプリケーション起動時に予期せぬエラーが発生しました");
}
}
}).create().show();
}
});
if(isOveLay){
gateView.getGoPlayerB().setVisibility(View.GONE);//別プロセスにならないように
}else{
gateView.getGoPlayerB().setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," getGoPlayerB");
close_noanimation();
if(CommunityTab.getCommunityTab() != null && liveinfo != null){
CommunityTab.getCommunityTab().startFlashPlayer(liveinfo);
}
}
});
}
update(sessionid);
}
public void onConfigChanged(Configuration newConfig){
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," Gate onConfigChanged");
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
if(tagDialog != null)tagDialog.onConfigChanged(gateView.getHeight());
commu_text.setWidth(gateView.getHeight() - 40);
tag_text.setWidth(gateView.getHeight() - 40);
desc_text.setWidth(gateView.getHeight() - 40);
title_text.setWidth(gateView.getHeight() - 40);
gateView.getTagLnkB().setLayoutParams(new TableRow.LayoutParams(gateView.getHeight()/7,80));
gateView.getCommunityLinkB().setLayoutParams(new TableRow.LayoutParams(gateView.getHeight()/7,80));
gateView.getBrowserLinkB().setLayoutParams(new TableRow.LayoutParams(gateView.getHeight()/7,80));
gateView.snsLnkB().setLayoutParams(new TableRow.LayoutParams(gateView.getHeight()/7,80));
gateView.getCopyB().setLayoutParams(new TableRow.LayoutParams(gateView.getHeight()/7,80));
gateView.getGoPlayerB().setLayoutParams(new TableRow.LayoutParams(gateView.getHeight()/4,80));
//goPlayerは自動的になるので大丈夫
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
if(tagDialog != null)tagDialog.onConfigChanged(gateView.getWidth());
commu_text.setWidth(gateView.getWidth() - 40);
tag_text.setWidth(gateView.getWidth() - 40);
desc_text.setWidth(gateView.getWidth() - 40);
title_text.setWidth(gateView.getWidth() - 40);
gateView.getCommuName().setWidth(gateView.getWidth()-40);
gateView.getTagLnkB().setLayoutParams(new TableRow.LayoutParams(gateView.getWidth()/7,80));
gateView.getCommunityLinkB().setLayoutParams(new TableRow.LayoutParams(gateView.getWidth()/7,80));
gateView.getBrowserLinkB().setLayoutParams(new TableRow.LayoutParams(gateView.getWidth()/7,80));
gateView.snsLnkB().setLayoutParams(new TableRow.LayoutParams(gateView.getWidth()/7,80));
gateView.getCopyB().setLayoutParams(new TableRow.LayoutParams(gateView.getWidth()/7,80));
gateView.getGoPlayerB().setLayoutParams(new TableRow.LayoutParams(gateView.getWidth()/4,80));
}
if(tweetDialog != null && tweetDialog.isShowing())tweetDialog.onConfigChanged(ACT);
}
/**
* 透明ACTからプログレスバーを触ると何故かここだけ
* android.view.ViewRoot$CalledFromWrongThreadException
* 言われるので分けた
* いままでと何が違うのだろう?
* @author Owner
*
*/
class SetProgress extends AsyncTask<Integer,Void,Integer>{
@Override
protected Integer doInBackground(Integer... params) {
return params[0];
}
@Override
protected void onPostExecute(Integer arg){
if(p != null){
try{
p.setProgress(arg);
}catch(IllegalArgumentException e){
e.printStackTrace();
}
}
}
}
public class BackGroundUpdate extends AsyncTask<String, Void, ErrorCode> {
@Override
protected ErrorCode doInBackground(String... arg0) {
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," Call Gate BackGroundUpdate");
ErrorCode error = ((NLiveRoid) ACT.getApplicationContext())
.getError();
if (error == null) {
return null;
} else if (error.getErrorCode() != 0) {
return error;
}else if(arg0[0] == null){
return null;
}// セッション取得
if (error.getErrorCode() != 0) {
return null;
}
if (p != null) {
new SetProgress().execute(10);
}
InputStream source = Request.doGetToInputStreamFromFixedSession(
arg0[0],
String.format(URLEnum.GATE, liveinfo.getLiveID()), error);
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," source " + source);
if (source == null) {
return null;
}
if (p != null) {
new SetProgress().execute(15);
}
try {
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," GateUpdate startGateParser");
GateParser handler = new GateParser(this, error,liveinfo);
org.ccil.cowan.tagsoup.Parser parser = new org.ccil.cowan.tagsoup.Parser();
parser.setContentHandler(handler);
parser.parse(new InputSource(source));
} catch (org.xml.sax.SAXNotRecognizedException e) {
// Should not happen.
e.printStackTrace();
throw new RuntimeException(e);
} catch (org.xml.sax.SAXNotSupportedException e) {
// Should not happen.
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
long startT = System.currentTimeMillis();
while (ENDFLAG) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
ENDFLAG = false;
break;
}catch(IllegalArgumentException e){
e.printStackTrace();
ENDFLAG = false;
break;
}
if(System.currentTimeMillis()-startT>30000){
error.setErrorCode(-10);
ENDFLAG = false;
return error;
}
}
return error;
}
protected void onPostExecute(ErrorCode arg) {
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," GateUpdate onPostExecute --- ");
if (p != null) {
p.setProgress(95);
}
if (arg == null) {
MyToast.customToastShow(ACT, "放送詳細の取得に失敗しました");
} else if (arg.getErrorCode() != 0) {
arg.showErrorToast();
} else {
// 取得成功
if(liveinfo == null){
MyToast.customToastShow(ACT, "放送詳細の取得に失敗しました");
return ;
}
String[] tagArray = liveinfo.getTags().split("<<TAGXXX>>");
tagList = new String[tagArray.length - 1];// splitで最初のタグは無効な文字列が入っている
String result = "";
for (int i = 1; i < tagArray.length; i++) {
tagList[i - 1] = tagArray[i];
result += tagArray[i] + " ";
}
if(liveinfo.getTsReserveToken() != null){
gateView.getReserveBt().setVisibility(View.VISIBLE);
gateView.getReserveBt().setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
new ReserveFirstTask().execute();
}
});
}
tag_text.setText(result);
title_text.setText(liveinfo.getTitle()==null? URLEnum.HYPHEN:liveinfo.getTitle());
desc_text.setText(getSpannable(liveinfo.getDescription()==null? URLEnum.HYPHEN:liveinfo.getDescription()));
commu_text.setText(getSpannable(liveinfo.getCommunity_info()==null? URLEnum.HYPHEN:liveinfo.getCommunity_info()));
gateView.getCommuName().setText(liveinfo.getCommunityName()==null? URLEnum.HYPHEN:liveinfo.getCommunityName());
gateView.getOwnerName().setText(liveinfo.getOwnerName()==null? URLEnum.HYPHEN:liveinfo.getOwnerName());
}
removeProgress();
}
public void finishCallBack(LiveInfo linfo) {
if (p != null) {
new SetProgress().execute(80);
}
ENDFLAG = false;
liveinfo = linfo;
}
}
public void update(String sessionid) {
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," Call update" + (sessionid == null? "sNULL":"sOK"));
addProgress();
new BackGroundUpdate().execute(sessionid);
}
private void addProgress() {
// プログレスバー処理
removeProgress();
TranslateAnimation pAnimation = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
pAnimation.setDuration(400);
pAnimation.setFillAfter(true);
try{
// ここでfindViewByIdせざるおえないのかな~
p = (ProgressBar) gateView.getPParent().findViewById(
R.id.ProgressBarHorizontal);// 毎回生成しないとできない
p.setMax(100);
p.setProgress(1);
}catch(IllegalArgumentException e){//背面の時にGateでActivity初期化と画面回転との関係でなる
e.printStackTrace();
return;
}
if(gateView.getPArea().getChildCount() > 0){
gateView.getPArea().removeView(p);
}
gateView.getPArea().addView(p, new LinearLayout.LayoutParams(-1, -1));
p.startAnimation(pAnimation);
gateView.getMainTable().setPadding(0, 35,0,0);
}
private void removeProgress() {
if (p != null) {
TranslateAnimation animation = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 1.0f);
animation.setDuration(400);
animation.setFillAfter(true);
try{
p.startAnimation(animation);
p.setProgress(100);
gateView.getPArea().removeAllViews();
p.setProgress(0);
}catch(IllegalArgumentException e){//背面の時にGateでActivity初期化と画面回転との関係でなる
e.printStackTrace();
return;
}
gateView.getMainTable().setPadding(0,30,0,0);
}
}
public void show(Configuration newConfig) {
isOpened = true;
if(gateView == null){//通信不通でなる
return;
}
gateView.getView().setVisibility(View.VISIBLE);
TranslateAnimation animation = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
animation.setDuration(300);
animation.setFillAfter(true);
gateView.getView().setAnimation(animation);
onConfigChanged(newConfig);//ここでボタンがアドされる
animation.start();
}
public void close() {
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," Gate close ---- ");
TranslateAnimation animation = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 1.0f);
animation.setDuration(200);
animation.setFillAfter(true);
if(TransDiscr.getACT() != null){
TransDiscr.getACT().finish();
}
if(gateView == null){
return;
}
gateView.getView().setAnimation(animation);
animation.start();
animation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationEnd(Animation arg0) {
close_noanimation();
}
@Override
public void onAnimationRepeat(Animation arg0) {
}
@Override
public void onAnimationStart(Animation arg0) {
}
});
}
public void close_noanimation() {
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid"," Gate close_noanimation ---- ");
if(tweetDialog != null && tweetDialog.isShowing())return;//TweetDialog表示中は画面回転でレイアウトがおかしくなるので閉じない
isOpened = false;
if(gateView == null){
return;
}
View v = gateView.getView();
if(v == null){
return;
}
ViewGroup vg = (ViewGroup) gateView.getView().getParent();
if (vg != null) {
vg.removeView(gateView.getView());
}
}
/**
* getPlayerにオーナーIDを取得に行くだけ
*
*/
class OwnerParseTask extends AsyncTask<String,Void,ErrorCode>{
@Override
protected ErrorCode doInBackground(String... arg0) {
ErrorCode error = ((NLiveRoid) ACT.getApplicationContext())
.getError();
if (error == null) {
return null;
} else if (error.getErrorCode() != 0) {
error.setErrorCode(-28);
return error;
}else if(arg0[0] == null){
return null;
}
// セッション取得
if (error.getErrorCode() != 0) {
error.setErrorCode(-28);
return error;
}
if (p != null) {
p.setProgress(10);
}
if(liveinfo == null || liveinfo.getLiveID() == null){
error.setErrorCode(-28);
return error;
}
InputStream source = Request.doGetToInputStreamFromFixedSession(
arg0[0],URLEnum.GETPLAYER + liveinfo.getLiveID(), error);
if (source == null) {
error.setErrorCode(-28);
return error;
}
if (p != null) {
p.setProgress(15);
}
byte[] b = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int size = 0;
byte[] byteArray = new byte[1024];
try {
while ((size = source.read(byteArray)) != -1) {
bos.write(byteArray, 0, size);
}
} catch (IOException e) {
e.printStackTrace();
}
b = bos.toByteArray();
if(b == null ){
error.setErrorCode(-28);
return error;
}
String result = XMLparser.getLiveInfoInputStreamOnlyOwner(b);
if(result == null){
error.setErrorCode(-28);
return error;
}else{
liveinfo.setOwnerID(result);
}
Uri uri = Uri.parse(URLEnum.USERPAGE + result);
Intent i = new Intent(Intent.ACTION_VIEW);
i.addCategory(Intent.CATEGORY_BROWSABLE);
i.setDataAndType(uri, "text/html");
ACT.startActivityForResult(i,CODE.RESULT_REDIRECT);//リダイレクトコード
// Log.d("log","RESULT " + result);
return error;
}
@Override
protected void onPostExecute(ErrorCode error){
if(error == null){
MyToast.customToastShow(ACT, "放送主の情報取得に失敗しました");//エラーがNULLだと取得失敗よりおかしいけど。。
}else if(error.getErrorCode() != 0){
error.showErrorToast();
}
}
}
//TSの予約ボタンタップ時の動作
class ReserveFirstTask extends AsyncTask<Void,Void,Integer>{
private ProgressDialog pd;
private ErrorCode error;
protected ReserveFirstTask(){
pd = new ProgressDialog(ACT);
pd.setMessage("情報取得中");
pd.show();
error = ((NLiveRoid) ACT.getApplicationContext())
.getError();
}
@Override
public void onCancelled(){
super.onCancelled();
if(pd != null && pd.isShowing())pd.cancel();
}
@Override
protected Integer doInBackground(Void... arg0) {
if (error == null) {
return -1;
} else if (error.getErrorCode() != 0) {
return 0;
}
// セッション取得
String session = Request.getSessionID(error);
if (error.getErrorCode() != 0) {
return 0;
}
if(liveinfo == null || liveinfo.getLiveID() == null){
error.setErrorCode(-28);
return 0;
}
String url = String.format(URLEnum.RESERVATION_FIRST ,liveinfo.getLiveID().replace("lv", ""),liveinfo.getLiveID(),liveinfo.getLiveID());
if(NLiveRoid.isDebugMode)Log.d("NLIveRoid","ReserveCommand0 " + url );
InputStream is = Request.doGetToInputStreamFromFixedSession(session,
url, error);
if(is == null){
return -2;
}else if (error.getErrorCode() != 0) {
error.setErrorCode(-28);
return 0;
}
byte[] b = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int size = 0;
byte[] byteArray = new byte[1024];
try {
while ((size = is.read(byteArray)) != -1) {
bos.write(byteArray, 0, size);
}
} catch (IOException e) {
e.printStackTrace();
}
b = bos.toByteArray();
String source;
try {
source = new String(b,"UTF-8");
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid","RESERVE0 response " + source);
Matcher ulck = Pattern.compile("ulck_[0-9]+").matcher(source);
if(ulck.find()){
liveinfo.setTsReserveToken(ulck.group());
}else{
return -3;
}
} catch (UnsupportedEncodingException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
return 0;
}
@Override
protected void onPostExecute(Integer arg){
if(pd != null && pd.isShowing())pd.cancel();
if(arg == 0 && error != null && error.getErrorCode() != 0){
error.showErrorToast();
}else if(arg == -1){
MyToast.customToastShow(ACT, "不明のエラーでした");
}else if(arg == -2){
MyToast.customToastShow(ACT, "予約に必要な情報取得に失敗しました");
}else if(arg == -3){
new AlertDialog.Builder(ACT)
.setMessage("(コミュニティ限定、予約済み、又は有料CHや公式等でした)\n生放送マイページをブラウザで開きますか?")
.setPositiveButton("YES", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.addCategory(Intent.CATEGORY_BROWSABLE);
i.setDataAndType(Uri.parse(URLEnum.MYPAGE), "text/html");
ACT.startActivity(i);
}
}).setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).create().show();
}else{
new AlertDialog.Builder(ACT)
.setMessage("この放送を予約しますか?")
.setPositiveButton("予約する", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new ReserveSecondTask().execute();
}
})
.setNegativeButton("キャンセル", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {}
}).create().show();
}
}
class ReserveSecondTask extends AsyncTask<Void,Void,Integer>{
@Override
protected Integer doInBackground(Void... params) {
String session = Request.getSessionID(error);
if (error.getErrorCode() != 0) {
return 0;
}
if(liveinfo == null || liveinfo.getLiveID() == null){
error.setErrorCode(-28);
return 0;
}
try {
HttpURLConnection con = (HttpURLConnection)new URL(URLEnum.RESERVATION_FIRST.split("\\?")[0]).openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Cookie", session);
con.setDoOutput(true);
PrintStream out = new PrintStream(con.getOutputStream());
out.print("mode=regist&vid="+liveinfo.getLiveID().replace("lv", "")+"&token="+liveinfo.getTsReserveToken());
InputStream is = con.getInputStream();
if(is == null){
return -2;
}
byte[] b = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int size = 0;
byte[] byteArray = new byte[1024];
while ((size = is.read(byteArray)) != -1) {
bos.write(byteArray, 0, size);
}
b = bos.toByteArray();
String source = new String(b,"UTF-8");
if(NLiveRoid.isDebugMode)Log.d("NLiveRoid","RESERVE2 response " + source);
Matcher regist_finish = Pattern.compile("id=\"regist_finished").matcher(source);
if(regist_finish.find()){
return 1;
}else{
return -3;
}
} catch (UnsupportedEncodingException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
} catch (MalformedURLException e1) {
// TODO 自動生成された catch ブロック
e1.printStackTrace();
} catch (IOException e1) {
// TODO 自動生成された catch ブロック
e1.printStackTrace();
}
return 0;
}
@Override
protected void onPostExecute(Integer arg){
if(pd != null && pd.isShowing())pd.cancel();
if(arg == 0 && error != null && error.getErrorCode() != 0){
error.showErrorToast();
}else if(arg == -1){
MyToast.customToastShow(ACT, "不明のエラー2でした");
}else if(arg == -2){
MyToast.customToastShow(ACT, "予約2に必要な情報取得に失敗しました");
}else if(arg == -3){
MyToast.customToastShow(ACT, "予約2に必要なTokenの取得に失敗しました");
}else if(arg == 1){
MyToast.customToastShow(ACT, "予約しました");
}
}
}
}
/**
* isOpenedを取得します。
*
* @return isOpened
*/
public boolean isOpened() {
return isOpened;
}
/**
* isOpenedを設定します。
*
* @return isOpened
*/
public void setOpened(boolean isopen) {
isOpened = isopen;
}
class TextSelectArea extends TextView {
private TableLayout pView;
private Rect rect;
// Spannable インターフェイスは SPAN を組み込む機能
private int scrollVert;
private int scrollHor;
public TextSelectArea(Context context, TableLayout pView) {
super(context);
setTextColor(Color.BLACK);
rect = new Rect();
this.pView = pView;
}
// Viewの座標系から文字オフセットに変換
public int getOffset(int x, int y) {
x += pView.getScrollX();
y += pView.getScrollY();
// getLineTop(line)でこのViewのその行のy座標
// getOffsetForHorizontal(line,X座標)でこのViewのその行のそのX座標だと全体の何文字目か
Layout l = getLayout();
int line = l.getLineForVertical(y);
if (line == 0 && y < l.getLineTop(line))
return 0;
if (line >= l.getLineCount() - 1 && y >= l.getLineTop(line + 1))
return l.getText().length();
int offset = l.getOffsetForHorizontal(line, x);
return offset;
}
// ドラッグ終了位置を更新
private void updateDragSelection(int x, int y, boolean finish) {
// if(isSelectMode){
// pView.requestDisallowInterceptTouchEvent(true);//選択モードじゃなければスクロールする
// }else{
// pView.requestDisallowInterceptTouchEvent(false);
// }
if (mOffsetDragStart != -1) {
// ScrollViewとの親和性のため、移動中の誤差は無視する
if (!finish) {
int dx = x - mDragStartX;
if (dx < 0)
dx = -dx;
int dy = y - mDragStartY;
if (dy < 0)
dy = -dy;
int lh = getLineHeight();
// 1行の高さに対して横方向3割、縦方向7割くらい
if (dx * 10 < lh * 3 && dy * 10 < lh * 7)
return;
} else if (isFinished) {
title_text.clearSelect();
desc_text.clearSelect();
}
mOffsetDragEnd = getOffset(x, y);
getGlobalVisibleRect(rect);
// Log.d("log","START " + mOffsetDragStart +" " + mOffsetDragEnd
// + " " + x + " " + y + " rect " + rect.left + " " +
// rect.right);
if (mOffsetDragStart < mOffsetDragEnd) {
clipbordText = getText().toString();
Spannable sn = factory.newSpannable(clipbordText);
sn.setSpan(new BackgroundColorSpan(Color.BLACK),
mOffsetDragStart, mOffsetDragEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
setText(sn);
} else if (mOffsetDragEnd < mOffsetDragStart) {
clipbordText = getText().toString();
Spannable sn = factory.newSpannable(clipbordText);
sn.setSpan(new BackgroundColorSpan(Color.BLACK),
mOffsetDragEnd, mOffsetDragStart,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
setText(sn);
} else if (mOffsetDragStart == mOffsetDragEnd) {
title_text.clearSelect();
desc_text.clearSelect();
}
if (finish) {
isFinished = true;
}
}
}
private void waitMoment() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}catch(IllegalArgumentException e){
e.printStackTrace();
}
}
public void clearSelect() {
String nowText = getText().toString();
clipbordText = "";// 空文字
Spannable sn = factory.newSpannable(nowText);
sn.setSpan(new BackgroundColorSpan(Color.WHITE), 0,
nowText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
setText(sn);
}
}
/**
* 文字列からセットできるSpannableに変換
*
* @param str
* @return
*/
private Spannable getSpannable(String str) {
// それぞれのタグを処理する
ArrayList<String> fIndex = new ArrayList<String>();
ArrayList<String> uIndex = new ArrayList<String>();
ArrayList<String> sIndex = new ArrayList<String>();
ArrayList<String> iIndex = new ArrayList<String>();
ArrayList<String> bIndex = new ArrayList<String>();
int i = 0;
int j = 0;
int k = 0;
String[] temp = null;
String size = "1";
String color = "#000000";
Pattern sizept = Pattern.compile("size");
Pattern colorpt = Pattern.compile("color");
Matcher mc = null;
HashMap<String, String> colorMap = ((NLiveRoid) ACT
.getApplicationContext()).getColorMap();
//改行なくす
str = str.replaceAll("\n", "");
str = str.replaceAll("<br>", "\n");
//とりあえずu i s a なし
str = str.replaceAll("<u>|</u>|<i>|</i>|<s>|</s>|<b>|</b>","");
for(int links = 0; links < 100; links++){
str = str.replaceAll("<<LINK"+links+">>.*<<LINK"+links+">>","");
}
int isNest = 0;
ArrayList<Integer> nest = new ArrayList<Integer>();
ALLCANCEL://チャンネルとかで、fontタグを無視してテキスト読み込み
// fontタグ
while (true) {
i = str.indexOf("<font",0);//一番上の階層のフォントタグ
if (i == -1) {
break;
}
// 終了タグがあるかを調べる パース自体が失敗してたらここまでが全て適応される
k = str.indexOf("</font>", i);
if (k == -1) {
break;// 無ければ適応しない
}
nest.add(i);//フォントタグ発見
while(true){//入れ子のスタート位置を全て入れておく
isNest = str.indexOf("<font",nest.get(nest.size()-1)+1);//
if(isNest == -1){
break;
}
if(isNest < k){//入れ子だった
int K = str.indexOf("</font>", isNest);
if (K == -1) {
break;// 無ければ適応しない
}
// Log.d("log","isNext " + isNest + " K " + k);
// Log.d("log","STR =-- " + str.substring(isNest, k));
k = K;
nest.add(isNest);
// Log.d("log","NEST SIZE " + nest.size());
}else{//入れ子じゃなければ終了
break;
}
}
while(true){
try{//公式や、チャンネルで、コミュニティが普通のサイトに繋がっている場合がある
// タグ終わりの>の位置を取得
j = str.indexOf(">", nest.get(nest.size()-1));//一番深い入れ子のfontタグ終わり
k = str.indexOf("</font>", nest.get(nest.size()-1));
//サイズと色の処理
temp = str.substring(nest.get(nest.size()-1), j).split("=| ");// 例 <font size=3でfont,size,3 color=#ff0000> でcolor,#ff0000
// サイズと色を配列にCSVで詰める
for (int x = 0; x < temp.length; x++) {
mc = sizept.matcher(temp[x]);
if (mc.find()) {
try {
size = temp[x + 1].substring(0, 1);// サイズは1桁という事を想定
} catch (NumberFormatException e) {
break;
}
size = temp[x + 1];
}
mc = null;
mc = colorpt.matcher(temp[x]);
if (mc.find()) {
// Log.d("log","F ---- " + temp[x+1]);
try {
if (colorMap.get(temp[x + 1]) != null) {//REDとかの時
color = colorMap.get(temp[x + 1]);
} else {
color = temp[x + 1].substring(0, 7);// #XXXXXXとかの時
}
} catch (StringIndexOutOfBoundsException e) {
break;
}
}
}
}catch(ArrayIndexOutOfBoundsException e){
Log.d("NLiveRoid","Gate Spannable error --- 0 - 0");
break ALLCANCEL;
}catch(StringIndexOutOfBoundsException e){
Log.d("NLiveRoid","Gate Spannable error --- 1 - 0");
break;
}
//ここでnest.get(nest.size()-1)~jまでがタグ、kからk+7までが終了タグ
//なのでそれらを計算して消す
//0からタグ前まで、インナーテキスト、タグ終わり後から最後まで
try{
// if(str.substring(0,nest.get(nest.size()-1)).length() > 10){
// Log.d("Log","BEFORE---- "+str.substring(0,nest.get(nest.size()-1)).substring(nest.get(nest.size()-1)-5, nest.get(nest.size()-1)));
// }
// Log.d("Log","STR " + str.substring(j+1, k));
// if(str.substring(k+7).length() > 10){
// Log.d("Log","K+7 " + str.substring(k+7).substring(0,8));
// }
str = str.substring(0,nest.get(nest.size()-1))+str.substring(j+1,k)+str.substring(k+7);
int tagLength = j-nest.get(nest.size()-1);//前に換算する長さ
//2回目以降のaddで、今のnestより後の位置ならその分前に持っていかなきゃいけない
for(int index = 0; index < fIndex.size(); index++){
if(Integer.parseInt(fIndex.get(index).split(",")[0]) > nest.get(nest.size()-1)){
fIndex.set(index, (Integer.parseInt(fIndex.get(index).split(",")[0])-tagLength-1)+","+
(Integer.parseInt(fIndex.get(index).split(",")[1])-tagLength-1)+","+
fIndex.get(index).split(",")[2]+","+
fIndex.get(index).split(",")[3]);
}
//後の位置に来るタグが入れ子になっていない場合終わりタグ(</font>)分も引かなければいけない
// if(Integer.parseInt(fIndex.get(index).split(",")[0]) > k-tagLength){
// fIndex.set(index, (Integer.parseInt(fIndex.get(index).split(",")[0])-7)+","+
// (Integer.parseInt(fIndex.get(index).split(",")[1])-7)+","+
// fIndex.get(index).split(",")[2]+","+
// fIndex.get(index).split(",")[3]);
// }
}
//上のstr = str.substring処理で、インナーが、str.substring(j+1,k)だから
fIndex.add((nest.get(nest.size()-1)) + "," + (k-tagLength-1) + "," + size + "," + color);//スタート、終わり、サイズ、位置
size = "1";
color = "#000000";
nest.clear();
break;
}catch(StringIndexOutOfBoundsException e){
Log.d("NLiveRoid","Gate Spannable ERROR --- 2 - 0");
break;
}
}
}
//この時点で最後に</font>とかあるのは不正なので消す
str = str.replaceAll("</font>", "");
//ここから先文字を消すと行数が合わなくなる
//とりあえず入れ子なし
// uタグ
// i = 0;
// k = 0;
// while (true) {
// i = str.indexOf("<u>", i);
// if (i != -1) {
// k = str.indexOf("</u>", i+1);
// if (k == -1) {
// Log.d("log","UTAG NO END ");
// break;
// }
// try{
// str = str.substring(0,i-1) + str.substring(i+3, k) + str.substring(k+4);
//
// Log.d("LOG","DEBUG 0--- " + i + " " + k + " " + str.substring(k-3));
// int diff = 3;//タグの長さ<u>
// for(int index = 0; index < fIndex.size(); index++){
// if(Integer.parseInt(fIndex.get(index).split(",")[0]) > i){
// fIndex.set(index, (Integer.parseInt(fIndex.get(index).split(",")[0])-diff)+","+
// (Integer.parseInt(fIndex.get(index).split(",")[1])-diff)+","+
// fIndex.get(index).split(",")[2]+","+
// fIndex.get(index).split(",")[3]);
// }
// }
//
// Log.d("Log","U " + i + " " + (k-diff));
// uIndex.add((i) + "," + (i+k-diff));
// i++;
// }catch(StringIndexOutOfBoundsException e){
// Log.d("log","ERROR BREAK UTAG---");
// break;
// }
// }else {
// break;
// }
// }
// // iタグ
// i = 0;
// k = 0;
// while (true) {
// i = str.indexOf("<i>", i);
// // Log.d("Log","I -- " + i);
// if (i != -1) {
// k = str.indexOf("</i>", i);
// if (k == -1) {
// break;
// }
// iIndex.add((i + 3) + "," + (k));
// } else {
// break;
// }
// i++;
// }
// // sタグ
// i = 0;
// k = 0;
// while (true) {
// i = str.indexOf("<s>", i);
// // Log.d("Log","S -- " + i);
// if (i != -1) {
// k = str.indexOf("</s>", i);
// if (k == -1) {
// break;
// }
// sIndex.add((i + 3) + "," + (k));
// } else {
// break;
// }
// i++;
// }
// // bタグ
// i = 0;
// k = 0;
// while (true) {
// i = str.indexOf("<b>", i);
// if (i != -1) {
// k = str.indexOf("</b>", i);
// if (k == -1) {
// break;
// }
// // Log.d("Log","B -- " + i + " " + k);
// bIndex.add((i + 3) + "," + (k));
// } else {
// break;
// }
// i++;
// }
temp = null;
Spannable sn = factory.newSpannable(str);
try {
// fサイズ
//スタートが早い方が優先されて適応してしまうのでソート
Collections.sort(fIndex,new fIndexComparator());
for (int a = 0; a < fIndex.size(); a++) {
temp = fIndex.get(a).split(",");
// Log.d("log","INDEX ---------- " + temp[0] + " " + temp[1] + " " + temp[3]);
// Log.d("log"," ----------" + str.substring(Integer.parseInt(temp[0]),Integer.parseInt(temp[1])));
if(Integer.parseInt(temp[0]) > str.length()){
break;
}else if(Integer.parseInt(temp[1]) > str.length()){
temp[1] = String.valueOf(str.length()-1);
}
sn.setSpan(
new AbsoluteSizeSpan(Integer.parseInt(temp[2])*2+20),
Integer.parseInt(temp[0]), Integer.parseInt(temp[1]),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
int tempCol = -1;
try{
tempCol = Color.parseColor(temp[3]);
}catch(IllegalArgumentException e){
continue;
}
sn.setSpan(new ForegroundColorSpan(tempCol),
Integer.parseInt(temp[0]), Integer.parseInt(temp[1]),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
temp = null;
// // f色
// for (int a = 0; a < fIndex.size(); a++) {
// temp = fIndex.get(a).split(",");
// Log.d("log","INDEX ---------- " + temp[0] + " " + temp[1]);
// int tempCol = 0;
// try {
// tempCol = Color.parseColor(temp[3]);
// } catch (IllegalArgumentException e) {
// Log.d("log", "COLOR ERROR --- " + temp[3]);
// break;
// }
// if(Integer.parseInt(temp[0]) > str.length()){
// break;
// }else if(Integer.parseInt(temp[1]) > str.length()){
// temp[1] = String.valueOf(str.length()-1);
// }
// sn.setSpan(new ForegroundColorSpan(tempCol),
// Integer.parseInt(temp[0]), Integer.parseInt(temp[1]),
// Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// }
// temp = null;
// u
// for (int a = 0; a < uIndex.size(); a++) {
// temp = uIndex.get(a).split(",");
// sn.setSpan(new UnderlineSpan(), Integer.parseInt(temp[0]),
// Integer.parseInt(temp[1]),
// Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// }
// temp = null;
// // i
// for (int a = 0; a < iIndex.size(); a++) {
// temp = iIndex.get(a).split(",");
// sn.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC),
// Integer.parseInt(temp[0]), Integer.parseInt(temp[1]),
// Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// }
// temp = null;
// // s
// for (int a = 0; a < sIndex.size(); a++) {
// temp = sIndex.get(a).split(",");
// sn.setSpan(new StrikethroughSpan(), Integer.parseInt(temp[0]),
// Integer.parseInt(temp[1]),
// Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// }
// temp = null;
// // b
// for (int a = 0; a < bIndex.size(); a++) {
// temp = bIndex.get(a).split(",");
// Log.d("log", "B " + temp[0] + " " + temp[1]);
// sn.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
// Integer.parseInt(temp[0]), Integer.parseInt(temp[1]),
// Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// }
} catch (NumberFormatException e) {
Log.d("NLiveRoid","Gate error 3-0 " );
e.printStackTrace();
} catch (IndexOutOfBoundsException e) {
Log.d("NLiveRoid","Gate error 3-1");
e.printStackTrace();
}
return sn;
}
private void fileWrite(String str){
try {
Context mContext = ACT.createPackageContext("nliveroid.nlr.main", ACT.CONTEXT_RESTRICTED);
FileOutputStream fos = mContext.openFileOutput("TEST.txt", ACT.MODE_WORLD_WRITEABLE);
fos.write(str.getBytes());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NameNotFoundException e) {
e.printStackTrace();
}
}
class fIndexComparator implements java.util.Comparator {
public int compare(Object s, Object t) {
return Integer.parseInt(((String)s).split(",")[0]) - Integer.parseInt(((String)t).split(",")[0]);
}
}
class ThumbNailTask extends AsyncTask<Void,Void,Integer>{
@Override
protected Integer doInBackground(Void... arg0) {
// サムネイルを取得
Bitmap bm = null;
if(liveinfo == null || liveinfo.getCommunityID() == null){
return -1;
}
ErrorCode error = ((NLiveRoid)ACT.getApplicationContext()).getError();
if(error == null){
return -2;
}
if(liveinfo.getCommunityID().contains(URLEnum.HYPHEN)){//公式
bm = Request.getImageForList(String.format(URLEnum.OFFICIALTHUMB,
liveinfo.getThumbnailURL()),error,0);
}else if(liveinfo.getCommunityID().contains("ch")){//チャンネル
bm = Request.getImageForList(String.format(URLEnum.BITMAPSCHANNEL,
liveinfo.getCommunityID()),error,0);
}else if(liveinfo.getCommunityID().contains("co")){//ユーザー
bm = Request.getImageForList(String.format(URLEnum.BITMAPSCOMMUNITY,
liveinfo.getCommunityID()),error,0);
}
if(bm != null){
liveinfo.setThumbnail(bm);
}else{
Log.d("Log","THUMBNAIL ERROR ");
}
return 0;
}
protected void onPostExecute(Integer arg){
if(arg == 0){
gateView.getCommuThumbView()
.setImageBitmap(liveinfo.getThumbnail());
gateView.getCommuThumbView().invalidate();
}
}
}
/**
* gateViewを取得します。
* @return gateView
*/
public GateView getGateView() {
return gateView;
}
}