//======================================================================== //$Id: IJetty.java 474 2012-01-23 03:07:14Z janb.webtide $ //Copyright 2008 Mort Bay Consulting Pty. Ltd. //------------------------------------------------------------------------ //Licensed under the Apache License, Version 2.0 (the "License"); //you may not use this file except in compliance with the License. //You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0 //Unless required by applicable law or agreed to in writing, software //distributed under the License is distributed on an "AS IS" BASIS, //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //See the License for the specific language governing permissions and //limitations under the License. //======================================================================== package org.mortbay.ijetty; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.lang.reflect.Method; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import org.eclipse.jetty.util.IO; import org.json.JSONObject; import org.mortbay.ijetty.component.AddressInfo; import org.mortbay.ijetty.html5webview.HTML5WebView; import org.mortbay.ijetty.javascript.ProxyBridge; import org.mortbay.ijetty.log.AndroidLog; import org.mortbay.ijetty.movieservice.MediaPlaybackService; import org.mortbay.ijetty.movieservice.MyFloatView; import org.mortbay.ijetty.network.DownloadManager; import org.mortbay.ijetty.network.IRequestListener; import org.mortbay.ijetty.network.InterfaceOp; import org.mortbay.ijetty.util.AndroidInfo; import org.mortbay.ijetty.util.ApkUtils; import org.mortbay.ijetty.util.IJettyToast; import org.mortbay.ijetty.util.PlayListUtil; import org.mortbay.ijetty.util.PropertiesUtils; import org.mortbay.ijetty.util.StringUtils; import android.app.Activity; import android.app.Dialog; import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.graphics.Point; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.text.Html; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import android.view.Display; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.view.View.OnClickListener; import android.webkit.WebSettings; import android.widget.Button; import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; /** * IJetty * * Main Jetty activity. Can start other activities: + configure + download * * Can start/stop services: + IJettyService */ public class IJetty extends Activity { private static final String TAG = "Jetty"; private static IJetty instance; public HTML5WebView mWebView; private PropertiesUtils mPropertiesUtil; public static final String __START_ACTION = "org.mortbay.ijetty.start"; public static final String __STOP_ACTION = "org.mortbay.ijetty.stop"; public static final String __START_MOVIE_ACTION = "org.mortbay.ijetty.movie.start"; public static final String __STOP_MOVIE_ACTION = "org.mortbay.ijetty.movie.stop"; public static final String __PORT = "org.mortbay.ijetty.port"; public static final String __NIO = "org.mortbay.ijetty.nio"; public static final String __SSL = "org.mortbay.ijetty.ssl"; public static final String __CONSOLE_PWD = "org.mortbay.ijetty.console"; public static final String __PORT_DEFAULT = "8080"; public static final boolean __NIO_DEFAULT = true; public static final boolean __SSL_DEFAULT = false; public static final String __CONSOLE_PWD_DEFAULT = "admin"; public static final String __WEBAPP_DIR = "webapps"; public static final String __ETC_DIR = "etc"; public static final String __CONTEXTS_DIR = "contexts"; public static final String __UPLOAD_DIR = "console/demo/upload"; public static final String __TMP_DIR = "tmp"; public static final String __WORK_DIR = "work"; public static final int __SETUP_PROGRESS_DIALOG = 0; public static final int __SETUP_DONE = 2; public static final int __SETUP_RUNNING = 1; public static final int __SETUP_NOTDONE = 0; public static final File __JETTY_DIR; private Button startButton; private Button stopButton; private Button configButton; private TextView footer; private TextView info; private TextView console; private ScrollView consoleScroller; private StringBuilder consoleBuffer = new StringBuilder(); private Runnable scrollTask; private ProgressDialog progressDialog; private Thread progressThread; private Handler handler; private BroadcastReceiver bcastReceiver; class ConsoleScrollTask implements Runnable { public void run() { consoleScroller.fullScroll(View.FOCUS_DOWN); } } /** * ProgressThread * * Handles finishing install tasks for Jetty. */ class ProgressThread extends Thread { private Handler _handler; public ProgressThread(Handler h) { _handler = h; } public void sendProgressUpdate (int prog) { Message msg = _handler.obtainMessage(); Bundle b = new Bundle(); b.putInt("prog", prog); msg.setData(b); _handler.sendMessage(msg); } public void run () { boolean updateNeeded = isUpdateNeeded(); //create the jetty dir structure File jettyDir = __JETTY_DIR; if (!jettyDir.exists()) { boolean made = jettyDir.mkdirs(); Log.i(TAG,"Made " + __JETTY_DIR + ": " + made); } sendProgressUpdate(10); //Do not make a work directory to preserve unpacked //webapps - this seems to clash with Android when //out-of-date webapps are deleted and then re-unpacked //on a jetty restart: Android remembers where the dex //file of the old webapp was installed, but it's now //been replaced by a new file of the same name. Strangely, //this does not seem to affect webapps unpacked to tmp? //Original versions of i-jetty created a work directory. So //we will delete it here if found to ensure webapps can be //updated successfully. File workDir = new File(jettyDir, __WORK_DIR); if (workDir.exists()) { Installer.delete(workDir); Log.i(TAG, "removed work dir"); } //make jetty/tmp File tmpDir = new File(jettyDir,__TMP_DIR); if (!tmpDir.exists()) { boolean made = tmpDir.mkdirs(); Log.i(TAG,"Made " + tmpDir + ": " + made); } else { Log.i(TAG,tmpDir + " exists"); } //make jetty/webapps File webappsDir = new File(jettyDir,__WEBAPP_DIR); if (!webappsDir.exists()) { boolean made = webappsDir.mkdirs(); Log.i(TAG,"Made " + webappsDir + ": " + made); } else { Log.i(TAG,webappsDir + " exists"); } //make jetty/etc File etcDir = new File(jettyDir,__ETC_DIR); if (!etcDir.exists()) { boolean made = etcDir.mkdirs(); Log.i(TAG,"Made " + etcDir + ": " + made); } else { Log.i(TAG,etcDir + " exists"); } sendProgressUpdate(30); //make Media2 File media2Dir = new File(AppConstants.getMediaSdFolder()); if(!media2Dir.exists()) { boolean made = media2Dir.mkdirs(); Log.i(TAG,"Made " + etcDir + ": " + made); } else { Log.i(TAG,media2Dir + " exists"); } File webdefaults = new File(etcDir,"webdefault.xml"); if (!webdefaults.exists() || updateNeeded) { //get the webdefaults.xml file out of resources try { InputStream is = getResources().openRawResource(R.raw.webdefault); OutputStream os = new FileOutputStream(webdefaults); IO.copy(is,os); Log.i(TAG,"Loaded webdefault.xml"); } catch (Exception e) { Log.e(TAG,"Error loading webdefault.xml",e); } } sendProgressUpdate(40); File realm = new File(etcDir,"realm.properties"); if (!realm.exists() || updateNeeded) { try { //get the realm.properties file out resources InputStream is = getResources().openRawResource(R.raw.realm_properties); OutputStream os = new FileOutputStream(realm); IO.copy(is,os); Log.i(TAG,"Loaded realm.properties"); } catch (Exception e) { Log.e(TAG,"Error loading realm.properties",e); } } sendProgressUpdate(50); File keystore = new File(etcDir,"keystore"); if (!keystore.exists() || updateNeeded) { try { //get the keystore out of resources InputStream is = getResources().openRawResource(R.raw.keystore); OutputStream os = new FileOutputStream(keystore); IO.copy(is,os); Log.i(TAG,"Loaded keystore"); } catch (Exception e) { Log.e(TAG,"Error loading keystore",e); } } sendProgressUpdate(60); //make jetty/contexts File contextsDir = new File(jettyDir,__CONTEXTS_DIR); if (!contextsDir.exists()) { boolean made = contextsDir.mkdirs(); Log.i(TAG,"Made " + contextsDir + ": " + made); } else { Log.i(TAG,contextsDir + " exists"); } sendProgressUpdate(70); try { PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(),0); if (pi != null) { setStoredJettyVersion(pi.versionCode); } } catch (Exception e) { Log.w(TAG, "Unable to get PackageInfo for i-jetty"); } //if there was a .update file indicating an update was needed, remove it now we've updated File update = new File(__JETTY_DIR, ".update"); if (update.exists()) update.delete(); sendProgressUpdate(80); //处理配置文件 File clientProps = new File(IJetty.__JETTY_DIR+"/"+IJetty.__ETC_DIR+"/properties.xml"); try { if(!(clientProps.exists()) || clientProps.length()==0) { //第一次安装解压 mPropertiesUtil.readPropertiesFileFromXML(IJetty.getInstance().getBaseContext().getAssets().open("properties.xml")); mPropertiesUtil.writePropertiesFileToXML(clientProps.getAbsolutePath()); InputStream is = IJetty.getInstance().getBaseContext().getAssets().open("console.war"); FileOutputStream fos = new FileOutputStream(AppConstants.getMediaSdFolder() + "/console.war"); byte[] buffer = new byte[1024]; int count = 0; while ((count = is.read(buffer)) > 0) { fos.write(buffer, 0, count); } fos.close(); is.close(); } else { //判断版本是否比软件assets文件夹里面自带的低,如果版本过低需要更新 mPropertiesUtil.readPropertiesFileFromXML(IJetty.getInstance().getBaseContext().getAssets().open("properties.xml")); //String propVersion = mPropertiesUtil.getVersion(); Log.w("smallstar-defaultPropVersion", mPropertiesUtil.getVersion()); int defaultPropVersion = Integer.parseInt(mPropertiesUtil.getVersion()); mPropertiesUtil.readPropertiesFileFromXML(clientProps.getAbsolutePath()); Log.w("smallstar-curPropVersion", mPropertiesUtil.getVersion()); int curPropVersion = Integer.parseInt(mPropertiesUtil.getVersion()); if(defaultPropVersion > curPropVersion) { //如果软件自带属性版本大于当前使用版本,说明软件升级的同时配置文件需要升级,使用软件里面自带的默认配置 //TODO:需要进一步处理不能被覆盖的属性 mPropertiesUtil.readPropertiesFileFromXML(IJetty.getInstance().getBaseContext().getAssets().open("properties.xml")); mPropertiesUtil.writePropertiesFileToXML(clientProps.getAbsolutePath()); //为低版本升级console.war Log.w(TAG, "copy console.war到SD卡升级"); InputStream is = IJetty.getInstance().getBaseContext().getAssets().open("console.war"); FileOutputStream fos = new FileOutputStream(AppConstants.getMediaSdFolder() + "/console.war"); byte[] buffer = new byte[1024]; int count = 0; while ((count = is.read(buffer)) > 0) { fos.write(buffer, 0, count); } fos.close(); is.close(); } Log.w(TAG, "==========================================================="); AppConstants.CLIENT_CUR_PLAYURL = mPropertiesUtil.getPlayUrl(); Log.w(TAG, AppConstants.CLIENT_CUR_PLAYURL); Log.w(TAG, "==========================================================="); // Toast.makeText(IJetty.getInstance().getApplicationContext(), AppConstants.CLIENT_CUR_PLAYURL, // Toast.LENGTH_SHORT).show(); PlayListUtil.playListVersion = mPropertiesUtil.getPlayListVersion(); ApkUtils.apkPushVersion = mPropertiesUtil.getApkPushVersion(); } } catch (IOException e) { // TODO Auto-generated catch block Log.w("smallstar------>","!clientProps.exists() error!!!!!!"); e.printStackTrace(); } sendProgressUpdate(100); } }; static { __JETTY_DIR = new File(Environment.getExternalStorageDirectory(),"jetty"); // if(StringUtils.replaceBlank(Build.MODEL).equals("EC3MBXboard") || StringUtils.replaceBlank(Build.MODEL).equals("EC3AdBoard")) // { // __JETTY_DIR = new File(AmlogicExt.getExternalStorage2Directory(),"jetty"); // } // else // { // __JETTY_DIR = new File(Environment.getExternalStorageDirectory(),"jetty"); // } // Ensure parsing is not validating - does not work with android System.setProperty("org.eclipse.jetty.xml.XmlParser.Validating","false"); // Bridge Jetty logging to Android logging System.setProperty("org.eclipse.jetty.util.log.class","org.mortbay.ijetty.AndroidLog"); org.eclipse.jetty.util.log.Log.setLog(new AndroidLog()); } public static IJetty getInstance() { return instance; } public IJetty () { super(); handler = new Handler () { public void handleMessage(Message msg) { int total = msg.getData().getInt("prog"); progressDialog.setProgress(total); if (total >= 100){ dismissDialog(__SETUP_PROGRESS_DIALOG); } } }; } public String formatJettyInfoLine (String format, Object ... args) { String ms = ""; if (format != null) ms = String.format(format, args); return ms+"<br/>"; } public void consolePrint(String format, Object... args) { String msg = String.format(format,args); if (msg.length() > 0) { consoleBuffer.append(msg).append("<br/>"); console.setText(Html.fromHtml(consoleBuffer.toString())); Log.i(TAG,msg); // Only interested in non-empty lines being output to Log } else { consoleBuffer.append(msg).append("<br/>"); console.setText(Html.fromHtml(consoleBuffer.toString())); } if (scrollTask == null) { scrollTask = new ConsoleScrollTask(); } consoleScroller.post(scrollTask); } protected int getStoredJettyVersion() { File jettyDir = __JETTY_DIR; if (!jettyDir.exists()) { return -1; } File versionFile = new File(jettyDir,"version.code"); if (!versionFile.exists()) { return -1; } int val = -1; ObjectInputStream ois = null; try { ois = new ObjectInputStream(new FileInputStream(versionFile)); val = ois.readInt(); return val; } catch (Exception e) { Log.e(TAG,"Problem reading version.code",e); return -1; } finally { if (ois != null) { try { ois.close(); } catch (Exception e) { Log.d(TAG,"Error closing version.code input stream",e); } } } } ////////////////////////////////////////// private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case AppConstants.MSG_SHOW_WEATHER: { AddressInfo addrInfo = AddressInfo.getInstance(); if (TextUtils.isEmpty(addrInfo.getCityName())) { // mWeatherTv.setText("联网失败"); // mWeatherTv.setVisibility(View.VISIBLE); // mWeatherImg1.setVisibility(View.GONE); // mWeatherImg2.setVisibility(View.GONE); return; } String info = null; if (!TextUtils.isEmpty(addrInfo.getProName())) { info = " " + addrInfo.getProName() + addrInfo.getCityName() + "市 "; } else { info = " " + addrInfo.getCityName() + "市 "; } String weatherInfo = info + msg.getData().getString("weatherMsg"); String imgUrl1 = msg.getData().getString("imgUrl1"); String imgUrl2 = msg.getData().getString("imgUrl2"); if (TextUtils.isEmpty(msg.getData().getString("weatherMsg"))) { // mWeatherTv.setText("联网失败"); // mWeatherTv.setVisibility(View.VISIBLE); // mWeatherImg1.setVisibility(View.GONE); // mWeatherImg2.setVisibility(View.GONE); return; } // mWeatherTv.setText(weatherInfo); // mWeatherTv.setVisibility(View.VISIBLE); // PhotoLoader loader = new PhotoLoader(MainActivity.this, // MainActivity.this, R.drawable.cloud_ico); // mWeatherImg1.setVisibility(View.VISIBLE); // mWeatherImg2.setVisibility(View.VISIBLE); // loader.loadPhoto(mWeatherImg1, imgUrl1); // loader.loadPhoto(mWeatherImg2, imgUrl2); break; } case AppConstants.MSG_INSTALL_COMPLETE: { if (msg.arg1 == ApkUtils.SUCCEEDED) { // Log.e("gary", "mHandler install success"); // String packagename = msg.getData().getString("packagename"); // if (packagename.equals("com.mylayout.app")) // ApkUtils.startApk(packagename, // ".MainActivity"); } else { // Log.e("gary", "mHandler install failed"); } } break; case AppConstants.MSG_REQUEST_DOWNLOAD: { long vStartToNowTime = System.currentTimeMillis() - StartupReceiver.START_TIME; if(vStartToNowTime > AppConstants.START_DOWNLOAD_TIME) { downloadMsg(msg); }else { Message vMsg = mHandler.obtainMessage(); mHandler.sendMessageDelayed(vMsg, AppConstants.START_DOWNLOAD_TIME - vStartToNowTime); } } break; case AppConstants.MSG_UPDATE_TIME: // mTimeTv.setText(mTimeStr); // if (mTimeStr.equals("00:00:00")) { // setDate(); // } else if (mTimeStr.endsWith("00:00")) { // updateAll(); // } else if (mTimeStr.endsWith("04:00")) { // WeatherAndAddressUtil.initAddressInfo(mHandler); // } break; case AppConstants.MSG_SHOW_MESSAGE: { String msgStr = msg.getData().getString("msg"); if (TextUtils.isEmpty(msgStr)) return; //vMainText.setText(msgStr.trim()); } break; case AppConstants.MSG_RELOCATE_LOGOIMG: { IJetty.this.finish(); // ApkUtils.startApk("com.mylayout.app", // "com.mylayout.app.MainActivity"); } case AppConstants.MSG_SUBMIT_APPS_LIST: // mHandler.removeMessages(AppConstants.MSG_SUBMIT_APPS_LIST); submitAppsList(mHandler); break; default: break; } }; }; private void downloadMsg(android.os.Message msg) { final String downloadUrl = msg.getData().getString( "downloadUrl"); final String savedName = msg.getData().getString("savedName"); DownloadManager.getInstance().startDownload(downloadUrl, savedName); } public static void submitAppsList(final Handler pHandler) { InterfaceOp.protoSubmmitAppsList(new IRequestListener() { public void onError(Exception e) { // TODO Auto-generated method stub pHandler.sendEmptyMessageDelayed(AppConstants.MSG_SUBMIT_APPS_LIST, AppConstants.DELAYED_SUBMIT_APPS_LIST); } public void onComplete(boolean isError, String errMsg, JSONObject respObj) { // TODO Auto-generated method stub if (isError)pHandler.sendEmptyMessageDelayed(AppConstants.MSG_SUBMIT_APPS_LIST, AppConstants.DELAYED_SUBMIT_APPS_LIST); } }); } public String getDisplayScreenSize() { WindowManager w = getWindowManager(); Display d = w.getDefaultDisplay(); DisplayMetrics metrics = new DisplayMetrics(); d.getMetrics(metrics); // since SDK_INT = 1; int widthPixels = metrics.widthPixels; int heightPixels = metrics.heightPixels; // includes window decorations (statusbar bar/menu bar) if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17) try { widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d); heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d); } catch (Exception ignored) { Log.e("-->smallstar","getDisplayScreenSize error"); } // includes window decorations (statusbar bar/menu bar) if (Build.VERSION.SDK_INT >= 17) try { Point realSize = new Point(); Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize); widthPixels = realSize.x; heightPixels = realSize.y; } catch (Exception ignored) { Log.e("-->smallstar","getDisplayScreenSize error"); } return String.valueOf(widthPixels) + "*" + String.valueOf(heightPixels); } @Override protected void onDestroy() { if (bcastReceiver != null) unregisterReceiver(bcastReceiver); super.onDestroy(); } @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); this.requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏 this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉信息栏 MainApplication.getInstance().setAppHandler(mHandler); instance = this; mWebView = new HTML5WebView(this); mWebView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY); mWebView.setHorizontalScrollBarEnabled(false);//水平不显示 mWebView.setVerticalScrollBarEnabled(false); //垂直不显示 mPropertiesUtil = new PropertiesUtils(); //设置开机自动运行 Intent autoStarIntent = new Intent("com.mortbay.ijetty.IJetty"); autoStarIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); autoStarIntent.addFlags(32); sendBroadcast(autoStarIntent); //获取屏幕分辨率 //DisplayMetrics dm = new DisplayMetrics(); //getWindowManager().getDefaultDisplay().getMetrics(dm); AppConstants.RESOLUTION = getDisplayScreenSize(); //String.valueOf(dm.widthPixels) + "*" + String.valueOf(getDisplayScreenHeight()); //dm.widthPixels,dm.heightPixels //处理配置文件 File clientProps = new File(IJetty.__JETTY_DIR+"/"+IJetty.__ETC_DIR+"/properties.xml"); try { if(clientProps.exists() && clientProps.length()!=0) { //判断版本是否比软件assets文件夹里面自带的低,如果版本过低需要更新 mPropertiesUtil.readPropertiesFileFromXML(IJetty.getInstance().getBaseContext().getAssets().open("properties.xml")); //String propVersion = mPropertiesUtil.getVersion(); Log.w("smallstar-defaultPropVersion", mPropertiesUtil.getVersion()); int defaultPropVersion = Integer.parseInt(mPropertiesUtil.getVersion()); mPropertiesUtil.readPropertiesFileFromXML(clientProps.getAbsolutePath()); Log.w("smallstar-curPropVersion", mPropertiesUtil.getVersion()); int curPropVersion = Integer.parseInt(mPropertiesUtil.getVersion()); if(defaultPropVersion > curPropVersion) { //如果软件自带属性版本大于当前使用版本,说明软件升级的同时配置文件需要升级,使用软件里面自带的默认配置 //TODO:需要进一步处理不能被覆盖的属性 mPropertiesUtil.readPropertiesFileFromXML(IJetty.getInstance().getBaseContext().getAssets().open("properties.xml")); mPropertiesUtil.writePropertiesFileToXML(clientProps.getAbsolutePath()); //为低版本升级console.war Log.w(TAG, "copy console.war到SD卡升级"); InputStream is = IJetty.getInstance().getBaseContext().getAssets().open("console.war"); FileOutputStream fos = new FileOutputStream(AppConstants.getMediaSdFolder() + "/console.war"); byte[] buffer = new byte[1024]; int count = 0; while ((count = is.read(buffer)) > 0) { fos.write(buffer, 0, count); } fos.close(); is.close(); } Log.w(TAG, "==========================================================="); AppConstants.CLIENT_CUR_PLAYURL = mPropertiesUtil.getPlayUrl(); Log.w(TAG, AppConstants.CLIENT_CUR_PLAYURL); Log.w(TAG, "==========================================================="); // Toast.makeText(IJetty.getInstance().getApplicationContext(), AppConstants.CLIENT_CUR_PLAYURL, // Toast.LENGTH_SHORT).show(); PlayListUtil.playListVersion = mPropertiesUtil.getPlayListVersion(); ApkUtils.apkPushVersion = mPropertiesUtil.getApkPushVersion(); } } catch (IOException e) { // TODO Auto-generated catch block Log.w("smallstar------>","!clientProps.exists() error!!!!!!"); e.printStackTrace(); } //启动服务:(心跳,网络状态) startService(new Intent(this, DaemonService.class)); //js交互接口 ProxyBridge jsBridge = new ProxyBridge(this); mWebView.addJavascriptInterface(jsBridge, "ia"); mWebView.setHorizontalScrollBarEnabled(false); setContentView(R.layout.jetty_controller); startButton = (Button)findViewById(R.id.start); startButton.setVisibility(View.GONE);//隐藏 stopButton = (Button)findViewById(R.id.stop); stopButton.setVisibility(View.GONE);//隐藏 configButton = (Button)findViewById(R.id.config); configButton.setVisibility(View.GONE);//隐藏 final Button downloadButton = (Button)findViewById(R.id.download); downloadButton.setVisibility(View.GONE);//隐藏 IntentFilter filter = new IntentFilter(); filter.addAction(__START_ACTION); filter.addAction(__STOP_ACTION); filter.addAction(__START_MOVIE_ACTION); filter.addCategory("default"); bcastReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { if (__START_ACTION.equalsIgnoreCase(intent.getAction())) { startButton.setEnabled(false); configButton.setEnabled(false); stopButton.setEnabled(true); consolePrint("<br/>Started Jetty at %s", new Date()); String[] connectors = intent.getExtras().getStringArray("connectors"); if (null != connectors) { for (int i=0;i<connectors.length;i++) consolePrint(connectors[i]); } printNetworkInterfaces(); if (AndroidInfo.isOnEmulator(IJetty.this)) consolePrint("Set up port forwarding to see i-jetty outside of the emulator."); //warFile = new File("file:///android_asset/console.war"); File file = new File(IJetty.__JETTY_DIR+"/"+IJetty.__WEBAPP_DIR+"/"+"console/settings/basicsettings.html"); if (file.exists()) { if(file.length() > 0) { //Not empty, do something here. //i-jetty启动后再加载设置web界面 setContentView(mWebView.getLayout()); //TODO:判断网络是否已经链接,如果已经链接则不显示设置页面。 int onlineTimeout = 0; do { if(onlineTimeout > 10) break; SystemClock.sleep(1000); onlineTimeout++; } while(!AppConstants.ONLINE_STATUS); if(AppConstants.ONLINE_STATUS)// { mWebView.getSettings().setCacheMode( WebSettings.LOAD_CACHE_ELSE_NETWORK); //mWebView.getSettings().setCacheMode( WebSettings.LOAD_NO_CACHE); mWebView.clearHistory(); mWebView.clearFormData(); mWebView.clearCache(true); mWebView.loadUrl(AppConstants.CLIENT_CUR_PLAYURL); } else mWebView.loadUrl("http://localhost:8080/console/settings/basicsettings.html"); } } } else if (__STOP_ACTION.equalsIgnoreCase(intent.getAction())) { startButton.setEnabled(true); configButton.setEnabled(true); stopButton.setEnabled(false); consolePrint("<br/> Jetty stopped at %s",new Date()); } else if(__START_MOVIE_ACTION.equalsIgnoreCase(intent.getAction())) { //但是如果service尚没有运行,系统会先调用onCreate(),然后调用onStartCommand(). Log.i(TAG, "onReceive() get Broadcast org.mortbay.ijetty.movie.start"); Intent mIntent = new Intent("createUI"); mIntent.setClass(context, MediaPlaybackService.class); context.startService(mIntent); } } }; registerReceiver(bcastReceiver, filter); // Watch for button clicks. startButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { if (isUpdateNeeded()) IJettyToast.showQuickToast(IJetty.this,R.string.loading); else { //TODO get these values from editable UI elements Intent intent = new Intent(IJetty.this,IJettyService.class); intent.putExtra(__PORT,__PORT_DEFAULT); intent.putExtra(__NIO,__NIO_DEFAULT); intent.putExtra(__SSL,__SSL_DEFAULT); intent.putExtra(__CONSOLE_PWD,__CONSOLE_PWD_DEFAULT); startService(intent); } } }); stopButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { stopService(new Intent(IJetty.this,IJettyService.class)); } }); configButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { IJettyEditor.show(IJetty.this); } }); downloadButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { IJettyDownloader.show(IJetty.this); } }); info = (TextView)findViewById(R.id.info); info.setVisibility(View.GONE); footer = (TextView)findViewById(R.id.footer); footer.setVisibility(View.GONE); console = (TextView)findViewById(R.id.console); console.setVisibility(View.GONE); consoleScroller = (ScrollView)findViewById(R.id.consoleScroller); consoleScroller.setVisibility(View.GONE); StringBuilder infoBuffer = new StringBuilder(); try { PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(),0); infoBuffer.append(formatJettyInfoLine ("i-jetty version %s (%s)",pi.versionName,pi.versionCode)); } catch (NameNotFoundException e) { infoBuffer.append(formatJettyInfoLine ("i-jetty version unknown")); } infoBuffer.append(formatJettyInfoLine("On %s using Android version %s",AndroidInfo.getDeviceModel(), AndroidInfo.getOSVersion())); info.setText(Html.fromHtml(infoBuffer.toString())); StringBuilder footerBuffer = new StringBuilder(); footerBuffer.append("<b>Project:</b> <a href=\"http://code.google.com/p/i-jetty\">http://code.google.com/p/i-jetty</a> <br/>"); footerBuffer.append("<b>Server:</b> http://www.eclipse.org/jetty <br/>"); footerBuffer.append("<b>Support:</b> http://www.intalio.com/jetty/services <br/>"); footer.setText(Html.fromHtml(footerBuffer.toString())); //软件打开后直接启动WEB服务 Intent intent = new Intent(IJetty.this,IJettyService.class); intent.putExtra(__PORT,__PORT_DEFAULT); intent.putExtra(__NIO,__NIO_DEFAULT); intent.putExtra(__SSL,__SSL_DEFAULT); intent.putExtra(__CONSOLE_PWD,__CONSOLE_PWD_DEFAULT); startService(intent); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mWebView.saveState(outState); } @Override public void onStop() { super.onStop(); mWebView.stopLoading(); } // @Override // public boolean dispatchTouchEvent(MotionEvent event) // { // // //获得触摸的坐标 // float x = event.getX(); // float y = event.getY(); // switch (event.getAction()) // { // //触摸屏幕时刻 // case MotionEvent.ACTION_DOWN: //// Log.w(TAG, "MotionEvent.ACTION_DOWN"); //// Toast.makeText(IJetty.getInstance().getApplicationContext(), "MotionEvent.ACTION_DOWN", //// Toast.LENGTH_SHORT).show(); // if (MyFloatView.mPlayViewPrepareStatus) // { // Log.e("smallstar", "MyFloatView.mPlayViewPrepareStatus is true!"); // MyFloatView.mPlayViewStatus = false; // MyFloatView.onExit(); // } // if(!ApkUtils.isBackgroundRunning(IJetty.getInstance(), "com.suncco.weather")) // { // Log.e("smallstar", "com.suncco.weather is not running."); // ApkUtils.startAppByPackageName("com.suncco.weather"); // } // else // { // Log.e("smallstar", "com.suncco.weather is running."); // ApkUtils.startAppByPackageName("com.suncco.weather"); // } // break; // //触摸并移动时刻 // case MotionEvent.ACTION_MOVE: // // break; // //终止触摸时刻 // case MotionEvent.ACTION_UP: // break; // } // return true; // } @Override public boolean dispatchKeyEvent(KeyEvent event) { Log.w(TAG, "onKeyDown"); if(event.getKeyCode() == KeyEvent.KEYCODE_BACK) { Log.w(TAG, "onKeyDown, KEYCODE_BACK"); if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { //响应事件的具体代码 if (MyFloatView.mPlayViewPrepareStatus) { Log.e("smallstar", "MyFloatView.mPlayViewPrepareStatus is true!"); MyFloatView.mPlayViewStatus = false; MyFloatView.onExit(); } if(mWebView.getOriginalUrl().equals("http://localhost:8080/console/settings/basicsettings.html")) { stopService(new Intent(this,DaemonService.class)); stopService(new Intent(this,IJettyService.class)); finish(); } else { //mWebView.loadUrl("http://localhost:8080/console/settings/index.html"); mWebView.loadUrl("http://localhost:8080/console/settings/basicsettings.html"); } } return true; } return super.dispatchKeyEvent(event); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); } public static void show(Context context) { final Intent intent = new Intent(context,IJetty.class); context.startActivity(intent); } @Override protected void onResume() { if (!SdCardUnavailableActivity.isExternalStorageAvailable()) { SdCardUnavailableActivity.show(this); } else { //work out if we need to do the installation finish step //or not. We do it iff: // - there is no previous jetty version on disk // - the previous version does not match the current version // - we're not already doing the update if (isUpdateNeeded()) { setupJetty(); } } if (IJettyService.isRunning()) { startButton.setEnabled(false); configButton.setEnabled(false); stopButton.setEnabled(true); //mWebView.loadUrl("http://localhost:8080/console/settings/basicsettings.html"); } else { startButton.setEnabled(true); configButton.setEnabled(true); stopButton.setEnabled(false); } super.onResume(); } @Override protected Dialog onCreateDialog(int id) { switch(id) { case __SETUP_PROGRESS_DIALOG: { progressDialog = new ProgressDialog(IJetty.this); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setMessage("Finishing initial install ..."); return progressDialog; } default: return null; } } private void printNetworkInterfaces() { try { Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces(); for (NetworkInterface ni : Collections.list(nis)) { Enumeration<InetAddress> iis = ni.getInetAddresses(); for (InetAddress ia : Collections.list(iis)) { consoleBuffer.append(formatJettyInfoLine("Network interface: %s: %s",ni.getDisplayName(),ia.getHostAddress())); } } } catch (SocketException e) { Log.w(TAG, e); } } protected void setStoredJettyVersion(int version) { File jettyDir = __JETTY_DIR; if (!jettyDir.exists()) { return; } File versionFile = new File(jettyDir,"version.code"); ObjectOutputStream oos = null; try { FileOutputStream fos = new FileOutputStream(versionFile); oos = new ObjectOutputStream(fos); oos.writeInt(version); oos.flush(); } catch (Exception e) { Log.e(TAG,"Problem writing jetty version",e); } finally { if (oos != null) { try { oos.close(); } catch (Exception e) { Log.d(TAG,"Error closing version.code output stream",e); } } } } /** * We need to an update iff we don't know the current * jetty version or it is different to the last version * that was installed. * * @return */ public boolean isUpdateNeeded () { //if no previous version file, assume update is required int storedVersion = getStoredJettyVersion(); if (storedVersion <= 0) return true; try { //if different previous version, update is required PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(),0); if (pi == null) return true; if (pi.versionCode != storedVersion) return true; //if /sdcard/jetty/.update file exists, then update is required File alwaysUpdate = new File(__JETTY_DIR,".update"); if (alwaysUpdate.exists()) { Log.i(TAG,"Always Update tag found " + alwaysUpdate); return true; } } catch (Exception e) { //if any of these tests go wrong, best to assume update is true? return true; } return false; } public void setupJetty() { showDialog(__SETUP_PROGRESS_DIALOG); progressThread = new ProgressThread(handler); progressThread.start(); }; }