package de.ecspride.javaclasses; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.AssetManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.Gravity; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.TextView; /** * Activity used to wait for the application to be connected to the PDP. * * @author alex * */ public class WaitPDPActivity extends Activity { // the default value of this field // will be setup automatically during // the instrumenting of an app. String mainActivityClassname = ""; Handler mHandler = new Handler(); @Override public void onCreate(Bundle savedInstance) { super.onCreate(savedInstance); Log.i("DroidForce", "Starting activity to synchronize with PDP..."); Log.i("DroidForce", "When PDP is initialized, activity '"+ mainActivityClassname +"' will be started."); // initiate connection to PDP InstrumentationHelper.initializeEventPEP(this); // Context.getResources() cannot be called in onCreate(). // Since, the background image is loaded from the assets directory // located in the apk, we setup the layout in a new thread which // is executed after onCreate() has returned. startThreadToPutLayout(); // Start a new thread which waits for the application to be // connected to the PDP. // Once the application is connected, it starts the "original" // activity. startThreadToCheckPDPConnection(); } /** * Setup the layout for the activity */ private void setLayout() { Log.i("DroidForce", "Setting up layout..."); LinearLayout llayout = new LinearLayout(this); LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); llayout.setBackgroundDrawable(loadBackground()); llayout.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL); TextView tv = new TextView(this); LayoutParams lpView = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); tv.setText("Powered by DroidForce."); tv.setLayoutParams(lpView); llayout.addView(tv); setContentView(llayout); } /** * */ public void startThreadToPutLayout() { Log.i("DroidForce", "Starting new thread to set layout."); new Thread(new Runnable() { @Override public void run() { mHandler.post(new Runnable() { @Override public void run() { setLayout(); } }); } }).start(); } /** * */ public void startThreadToCheckPDPConnection() { Log.i("DroidForce", "Starting new thread to check status of PDP connection."); // only start the "original activity" after 4 seconds // so that the user has time to see the background image new Thread(new Runnable() { @Override public void run() { while (true) { try { Log.i("DroidForce", "sleeping 2 seconds..."); Thread.sleep(4000); mHandler.post(new Runnable() { @Override public void run() { if (EventPEP.isBound()) { Log.i("DroidForce", "connected to PDP."); startOriginalActivity(); } else { Log.i("DroidForce", "no connection to PDP yet."); } } }); if (EventPEP.isBound) { break; } } catch (Exception e) { throw new RuntimeException("error: "+ e); } } } }).start(); Log.i("DroidForce", "End of onCreate()"); } /** * This method starts the 'original' activity. * * Remember that this code is added to the instrumented application. * After the instrumentation, 'mainActivityClassname' contains * the class name of the 'original' activity. */ private void startOriginalActivity() { Intent i = new Intent(); String targetClass = mainActivityClassname.replaceAll("\\.[^\\.]*$", ""); i.setClassName(targetClass, this.mainActivityClassname); Log.i("DroidForce", "start main activity with packageName = '" + targetClass + "' and className = '" + this.mainActivityClassname + "'..."); this.startActivity(i); } /** * Load background image from the assets directory. * @return Drawable object representing the background image. */ private Drawable loadBackground() { Resources r = getResources(); Log.d("DroidForce", "resources: "+ r); String[] files = null; try { files = r.getAssets().list(""); } catch (IOException e) { Log.e("DroidForce", "exception "+ e); e.printStackTrace(); } Log.d("DroidForce", "number of files in assets: "+ files.length); for (String s: files) { Log.d("DroidForce", "file in asset: "+ s); if (s.endsWith("protect.png")) { File file = copyFileFromAssetsToInternalStorage(s, true); String path = file.getAbsolutePath(); Log.d("DroidForce", "Path to file is '"+ path +"'"); return Drawable.createFromPath(path); } } throw new RuntimeException("error: drawable not found."); } private File copyFileFromAssetsToInternalStorage(String fileName, boolean forceRewrite) { String fileInternally = this.getFilesDir().toString() + File.separator + fileName; File file = new File(fileInternally); try { if (!file.exists() || forceRewrite) { copyFileFromAssetsToInternalStorage(getApplicationContext(), fileName, fileInternally); } } catch(Exception ex) { Log.e("ERROR", ex.getMessage()); } return file; } public static void copyFileFromAssetsToInternalStorage(Context context, String srcFile, String targetFolder) throws IOException{ copyAsset(context.getAssets(), srcFile, targetFolder); } public static boolean copyAsset(AssetManager assetManager, String fromAssetPath, String toPath) { InputStream in = null; OutputStream out = null; try { in = assetManager.open(fromAssetPath); new File(toPath).createNewFile(); out = new FileOutputStream(toPath); copyFile(in, out); in.close(); in = null; out.flush(); out.close(); out = null; return true; } catch(Exception e) { e.printStackTrace(); return false; } } private static void copyFile(InputStream in, OutputStream out) throws IOException { byte[] buffer = new byte[1024]; int read; while((read = in.read(buffer)) != -1){ out.write(buffer, 0, read); } } }