1 package com.svox.pico.voice.spa.esp; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.util.zip.ZipEntry; 8 import java.util.zip.ZipInputStream; 9 10 import android.app.Activity; 11 import android.content.Intent; 12 import android.content.res.AssetFileDescriptor; 13 import android.content.res.Resources; 14 import android.os.Bundle; 15 import android.speech.tts.TextToSpeech; 16 import android.util.Log; 17 import android.view.View; 18 import android.view.View.OnClickListener; 19 import android.widget.Button; 20 21 public class InstallerActivity extends Activity { 22 private static final int DATA_ROOT_DIRECTORY_REQUEST_CODE = 42; 23 private String rootDirectory = ""; 24 private InstallerActivity self; 25 private static boolean sInstallationSuccess = false; 26 private static boolean sIsInstalling = false; 27 private final static Object sInstallerStateLock = new Object(); 28 29 /** Called when the activity is first created. */ 30 @Override onCreate(Bundle savedInstanceState)31 public void onCreate(Bundle savedInstanceState) { 32 super.onCreate(savedInstanceState); 33 self = this; 34 Intent getRootDirectoryIntent = new Intent(); 35 getRootDirectoryIntent.setClassName("com.svox.pico", "com.svox.pico.CheckVoiceData"); 36 startActivityForResult(getRootDirectoryIntent, DATA_ROOT_DIRECTORY_REQUEST_CODE); 37 } 38 39 @Override onActivityResult(int requestCode, int resultCode, Intent data)40 public void onActivityResult(int requestCode, int resultCode, Intent data){ 41 super.onActivityResult(requestCode, resultCode, data); 42 if (requestCode == DATA_ROOT_DIRECTORY_REQUEST_CODE) { 43 rootDirectory = data.getStringExtra(TextToSpeech.Engine.EXTRA_VOICE_DATA_ROOT_DIRECTORY); 44 // only run the installer if there isn't another one running 45 synchronized (sInstallerStateLock) { 46 if (!sIsInstalling && !sInstallationSuccess) { 47 sIsInstalling = true; 48 runInstaller(); 49 } 50 } 51 } 52 } 53 runInstaller()54 private void runInstaller(){ 55 try { 56 Resources res = getResources(); 57 AssetFileDescriptor langPackFd = res 58 .openRawResourceFd(R.raw.svoxlangpack); 59 InputStream stream = langPackFd.createInputStream(); 60 61 (new Thread(new unzipper(stream))).start(); 62 } catch (IOException e) { 63 Log.e("PicoLangInstaller", "Unable to open langpack resource."); 64 e.printStackTrace(); 65 } 66 setContentView(R.layout.installing); 67 } 68 69 unzipLangPack(InputStream stream)70 private boolean unzipLangPack(InputStream stream) { 71 FileOutputStream out; 72 byte buf[] = new byte[16384]; 73 try { 74 ZipInputStream zis = new ZipInputStream(stream); 75 ZipEntry entry = zis.getNextEntry(); 76 while (entry != null) { 77 if (entry.isDirectory()) { 78 File newDir = new File(rootDirectory + entry.getName()); 79 newDir.mkdir(); 80 } else { 81 String name = entry.getName(); 82 File outputFile = new File(rootDirectory + name); 83 String outputPath = outputFile.getCanonicalPath(); 84 name = outputPath 85 .substring(outputPath.lastIndexOf("/") + 1); 86 outputPath = outputPath.substring(0, outputPath 87 .lastIndexOf("/")); 88 File outputDir = new File(outputPath); 89 outputDir.mkdirs(); 90 outputFile = new File(outputPath, name); 91 outputFile.createNewFile(); 92 out = new FileOutputStream(outputFile); 93 94 int numread = 0; 95 do { 96 numread = zis.read(buf); 97 if (numread <= 0) { 98 break; 99 } else { 100 out.write(buf, 0, numread); 101 } 102 } while (true); 103 out.close(); 104 } 105 entry = zis.getNextEntry(); 106 } 107 return true; 108 } catch (IOException e) { 109 e.printStackTrace(); 110 return false; 111 } 112 } 113 114 private class unzipper implements Runnable { 115 public InputStream stream; 116 unzipper(InputStream is)117 public unzipper(InputStream is) { 118 stream = is; 119 } 120 run()121 public void run() { 122 boolean result = unzipLangPack(stream); 123 synchronized (sInstallerStateLock) { 124 sInstallationSuccess = result; 125 sIsInstalling = false; 126 } 127 if (sInstallationSuccess) { 128 // installation completed: signal success (extra set to SUCCESS) 129 Intent installCompleteIntent = 130 new Intent(TextToSpeech.Engine.ACTION_TTS_DATA_INSTALLED); 131 installCompleteIntent.putExtra(TextToSpeech.Engine.EXTRA_TTS_DATA_INSTALLED, 132 TextToSpeech.SUCCESS); 133 self.sendBroadcast(installCompleteIntent); 134 finish(); 135 } else { 136 // installation failed 137 // signal install error if the activity is finishing (can't ask the user to retry) 138 if (self.isFinishing()) { 139 Intent installCompleteIntent = 140 new Intent(TextToSpeech.Engine.ACTION_TTS_DATA_INSTALLED); 141 installCompleteIntent.putExtra(TextToSpeech.Engine.EXTRA_TTS_DATA_INSTALLED, 142 TextToSpeech.ERROR); 143 self.sendBroadcast(installCompleteIntent); 144 } else { 145 // the activity is still running, ask the user to retry. 146 runOnUiThread(new retryDisplayer()); 147 } 148 } 149 } 150 } 151 152 153 public class retryDisplayer implements Runnable { run()154 public void run() { 155 setContentView(R.layout.retry); 156 Button retryButton = (Button) findViewById(R.id.retryButton); 157 retryButton.setOnClickListener(new OnClickListener() { 158 public void onClick(View arg0) { 159 // only run the installer if there isn't another one running 160 // (we only get here if the installer couldn't complete successfully before) 161 synchronized (sInstallerStateLock) { 162 if (!sIsInstalling) { 163 sIsInstalling = true; 164 runInstaller(); 165 } 166 } 167 } 168 }); 169 } 170 } 171 172 } 173