I'm using the ARexampleLocationBased tutorial ,the POIS ar correctly shown but the annottations are not shown ,,the program works correct but the billoboards image down the POI's are not visible
package pfg.proyecto.com.proyecto;
import android.view.View;
import com.metaio.sdk.ARELActivity;
public class ARELViewActivity extends ARELActivity
{
#Override
protected int getGUILayout()
{
return R.layout.activity_main;
}
public void onButtonClick(View v)
{
finish();
}
}
and this is the main activity code
package pfg.proyecto.com.proyecto;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextPaint;
import android.util.Log;
import android.view.View;
import com.metaio.cloud.plugin.util.MetaioCloudUtils;
import com.metaio.sdk.ARELInterpreterAndroidJava;
import com.metaio.sdk.ARViewActivity;
import com.metaio.sdk.MetaioDebug;
import com.metaio.sdk.jni.AnnotatedGeometriesGroupCallback;
import com.metaio.sdk.jni.EGEOMETRY_FOCUS_STATE;
import com.metaio.sdk.jni.IAnnotatedGeometriesGroup;
import com.metaio.sdk.jni.IGeometry;
import com.metaio.sdk.jni.IMetaioSDKCallback;
import com.metaio.sdk.jni.IRadar;
import com.metaio.sdk.jni.ImageStruct;
import com.metaio.sdk.jni.LLACoordinate;
import com.metaio.sdk.jni.Rotation;
import com.metaio.sdk.jni.SensorValues;
import com.metaio.sdk.jni.Vector3d;
import com.metaio.tools.io.AssetsManager;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.locks.Lock;
public class MainActivity extends ARViewActivity
{
private IAnnotatedGeometriesGroup mAnnotatedGeometriesGroup;
private MyAnnotatedGeometriesGroupCallback mAnnotatedGeometriesGroupCallback;
/**
* Geometries
*/
private IGeometry mLondonGeo;
private IGeometry mMunichGeo;
private IGeometry mRomeGeo;
private IGeometry mTokyoGeo;
private IGeometry mParisGeo;
private IRadar mRadar;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Set GPS tracking configuration
boolean result = metaioSDK.setTrackingConfiguration("GPS", false);
new LoadAssets().execute(0);
MetaioDebug.log("Tracking data loaded: " + result);
}
#Override
protected void onDestroy()
{
// Break circular reference of Java objects
if (mAnnotatedGeometriesGroup != null)
{
mAnnotatedGeometriesGroup.registerCallback(null);
}
if (mAnnotatedGeometriesGroupCallback != null)
{
mAnnotatedGeometriesGroupCallback.delete();
mAnnotatedGeometriesGroupCallback = null;
}
super.onDestroy();
}
#Override
public void onDrawFrame()
{
if (metaioSDK != null && mSensors != null)
{
SensorValues sensorValues = mSensors.getSensorValues();
float heading = 0.0f;
if (sensorValues.hasAttitude())
{
float m[] = new float[9];
sensorValues.getAttitude().getRotationMatrix(m);
Vector3d v = new Vector3d(m[6], m[7], m[8]);
v.normalize();
heading = (float)(-Math.atan2(v.getY(), v.getX()) - Math.PI / 2.0);
}
IGeometry geos[] = new IGeometry[] {mLondonGeo, mParisGeo, mRomeGeo, mTokyoGeo,};
Rotation rot = new Rotation((float)(Math.PI / 2.0), 0.0f, -heading);
for (IGeometry geo : geos)
{
if (geo != null)
{
geo.setRotation(rot);
}
}
}
super.onDrawFrame();
}
public void onButtonClick(View v)
{
finish();
}
#Override
protected int getGUILayout()
{
return R.layout.activity_main;
}
#Override
protected IMetaioSDKCallback getMetaioSDKCallbackHandler()
{
return null;
}
#Override
protected void loadContents()
{
mAnnotatedGeometriesGroup = metaioSDK.createAnnotatedGeometriesGroup();
mAnnotatedGeometriesGroupCallback = new MyAnnotatedGeometriesGroupCallback();
mAnnotatedGeometriesGroup.registerCallback(mAnnotatedGeometriesGroupCallback);
// Clamp geometries' Z position to range [5000;200000] no matter how close or far they are
// away.
// This influences minimum and maximum scaling of the geometries (easier for development).
metaioSDK.setLLAObjectRenderingLimits(5, 200);
// Set render frustum accordingly
metaioSDK.setRendererClippingPlaneLimits(10, 220000);
// let's create LLA objects for known cities
LLACoordinate munich = new LLACoordinate(48.142573, 11.550321, 0, 0);
LLACoordinate london = new LLACoordinate(51.50661, -0.130463, 0, 0);
LLACoordinate tokyo = new LLACoordinate(35.657464, 139.773865, 0, 0);
LLACoordinate rome = new LLACoordinate(41.90177, 12.45987, 0, 0);
LLACoordinate paris = new LLACoordinate(48.85658, 2.348671, 0, 0);
LLACoordinate parque = new LLACoordinate(36.465985, -6.201081, 0, 0);
// Load some POIs. Each of them has the same shape at its geoposition. We pass a string
// (const char*) to IAnnotatedGeometriesGroup::addGeometry so that we can use it as POI
// title
// in the callback, in order to create an annotation image with the title on it.
mLondonGeo = createPOIGeometry(london);
mAnnotatedGeometriesGroup.addGeometry(mLondonGeo, "London");
mParisGeo = createPOIGeometry(paris);
mAnnotatedGeometriesGroup.addGeometry(mParisGeo, "Paris");
mRomeGeo = createPOIGeometry(rome);
mAnnotatedGeometriesGroup.addGeometry(mRomeGeo, "Rome");
mTokyoGeo = createPOIGeometry(tokyo);
mAnnotatedGeometriesGroup.addGeometry(mTokyoGeo, "Tokyo");
File metaioManModel =
AssetsManager.getAssetPathAsFile(getApplicationContext(),
"metaioman.md2");
if (metaioManModel != null)
{
mMunichGeo = metaioSDK.createGeometry(metaioManModel);
if (mMunichGeo != null)
{
mMunichGeo.setTranslationLLA(munich);
mMunichGeo.setLLALimitsEnabled(true);
mMunichGeo.setScale(500);
}
else
{
MetaioDebug.log(Log.ERROR, "Error loading geometry: " + metaioManModel);
}
}
// create radar
mRadar = metaioSDK.createRadar();
mRadar.setBackgroundTexture(AssetsManager.getAssetPathAsFile(getApplicationContext(),
"radar.png"));
mRadar.setObjectsDefaultTexture(AssetsManager.getAssetPathAsFile(getApplicationContext(),
"yellow.png"));
mRadar.setRelativeToScreen(IGeometry.ANCHOR_TL);
// add geometries to the radar
mRadar.add(mLondonGeo);
mRadar.add(mMunichGeo);
mRadar.add(mTokyoGeo);
mRadar.add(mParisGeo);
mRadar.add(mRomeGeo);
}
private IGeometry createPOIGeometry(LLACoordinate lla)
{
final File path =
AssetsManager.getAssetPathAsFile(getApplicationContext(),
"ExamplePOI.obj");
if (path != null)
{
IGeometry geo = metaioSDK.createGeometry(path);
geo.setTranslationLLA(lla);
geo.setLLALimitsEnabled(true);
geo.setScale(100);
return geo;
}
else
{
MetaioDebug.log(Log.ERROR, "Missing files for POI geometry");
return null;
}
}
#Override
protected void onGeometryTouched(final IGeometry geometry)
{
MetaioDebug.log("Geometry selected: " + geometry);
mSurfaceView.queueEvent(new Runnable()
{
#Override
public void run()
{
mRadar.setObjectsDefaultTexture(AssetsManager.getAssetPathAsFile(getApplicationContext(),
"yellow.png"));
mRadar.setObjectTexture(geometry, AssetsManager.getAssetPathAsFile(getApplicationContext(),
"red.png"));
mAnnotatedGeometriesGroup.setSelectedGeometry(geometry);
}
});
}
final class MyAnnotatedGeometriesGroupCallback extends AnnotatedGeometriesGroupCallback
{
Bitmap mAnnotationBackground, mEmptyStarImage, mFullStarImage;
int mAnnotationBackgroundIndex;
ImageStruct texture;
String[] textureHash = new String[1];
TextPaint mPaint;
Lock geometryLock;
Bitmap inOutCachedBitmaps[] = new Bitmap[] {mAnnotationBackground, mEmptyStarImage, mFullStarImage};
int inOutCachedAnnotationBackgroundIndex[] = new int[] {mAnnotationBackgroundIndex};
public MyAnnotatedGeometriesGroupCallback()
{
mPaint = new TextPaint();
mPaint.setFilterBitmap(true); // enable dithering
mPaint.setAntiAlias(true); // enable anti-aliasing
}
#Override
public IGeometry loadUpdatedAnnotation(IGeometry geometry, Object userData, IGeometry existingAnnotation)
{
if (userData == null)
{
return null;
}
if (existingAnnotation != null)
{
// We don't update the annotation if e.g. distance has changed
return existingAnnotation;
}
String title = (String)userData; // as passed to addGeometry
LLACoordinate location = geometry.getTranslationLLA();
float distance = (float)MetaioCloudUtils.getDistanceBetweenTwoCoordinates(location, mSensors.getLocation());
Bitmap thumbnail = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
try
{
texture =
ARELInterpreterAndroidJava.getAnnotationImageForPOI(title, title, distance, "5", thumbnail,
null,
metaioSDK.getRenderSize(), MainActivity.this,
mPaint, inOutCachedBitmaps, inOutCachedAnnotationBackgroundIndex, textureHash);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (thumbnail != null)
thumbnail.recycle();
thumbnail = null;
}
mAnnotationBackground = inOutCachedBitmaps[0];
mEmptyStarImage = inOutCachedBitmaps[1];
mFullStarImage = inOutCachedBitmaps[2];
mAnnotationBackgroundIndex = inOutCachedAnnotationBackgroundIndex[0];
IGeometry resultGeometry = null;
if (texture != null)
{
if (geometryLock != null)
{
geometryLock.lock();
}
try
{
// Use texture "hash" to ensure that SDK loads new texture if texture changed
resultGeometry = metaioSDK.createGeometryFromImage(textureHash[0], texture, true, false);
}
finally
{
if (geometryLock != null)
{
geometryLock.unlock();
}
}
}
return resultGeometry;
}
#Override
public void onFocusStateChanged(IGeometry geometry, Object userData, EGEOMETRY_FOCUS_STATE oldState,
EGEOMETRY_FOCUS_STATE newState)
{
MetaioDebug.log("onFocusStateChanged for " + (String)userData + ", " + oldState + "->" + newState);
}
}
public class LoadAssets extends AsyncTask<Integer, Integer, Boolean> {
#Override
protected Boolean doInBackground(Integer... params) {
try
{
// Extract all assets and overwrite existing files if debug build
AssetsManager.extractAllAssets(getApplicationContext(), BuildConfig.DEBUG);
}
catch (IOException e)
{
MetaioDebug.log(Log.ERROR, "Error extracting assets: " + e.getMessage());
MetaioDebug.printStackTrace(Log.ERROR, e);
return false;
}
return true;
}
}
}
Somebody knows what is wrong?
if you use skd 5.3 or later you must copy assets/junaio folder of tutorial(example_SDK) into your assets folder so your poi shown.
i've just found it i am working on that right know. my poi.obj rotates...
Related
I have 231 sound files ( duration ~ 0.2 Sec each) of size 5.7 MB total to load into my android project. I am trying load them when the application starts using for loop like
for (int i = 0; i < 231; i++){
...
loadSoundAsset(i); //method to load the sound files
i++;
...
}
Yet the above method is taking too long to load the sound files. What should be done to load effectively many asset files into android project?
I create sample code for you. How to get faster? (I test it for assets files about 180 sounds files.)
MainActivity
public class MainActivity extends Activity implements TaskListener {
MultiLoader loader = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView view = new TextView(this);
view.setText("Loader");
setContentView(view);
}
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
loader = new MultiLoader(this, this);
loader.load("sound");
}
#Override
public void onTaskEnd() {
Vector<byte[]> soundDatas = loader.getData();
Log.e("MainActivity", "TaskEnd");
}
#Override
protected void onDestroy() {
loader.clear();
super.onDestroy();
}
}
MultiLoader
package com.fastload;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import java.util.regex.Pattern;
import android.content.Context;
import android.util.Log;
public class MultiLoader {
private int threadCount = 0;
private String[] mFiles;
private Vector<byte[]> fileContents = new Vector<byte[]>();
private Thread[] mQueue = null;
private Context mContext;
private TaskListener listener;
public MultiLoader(Context mContext, TaskListener listener) {
super();
this.mContext = mContext;
this.listener = listener;
}
public Vector<byte[]> getData(){
return fileContents;
}
public void reQueue(int index){
boolean status = true;
mQueue[index] = null;
for(Thread item : mQueue){
status &= (item == null);
}
if(status){
listener.onTaskEnd();
}
}
public void load(final String path){
initialize(path);
if(mFiles == null || (mFiles != null && mFiles.length < 1))
return;
mQueue = new Thread[threadCount];
for(int i = 0; i < threadCount; ++i){
int len = mFiles.length;
int piece = len / threadCount;
final int startIndex = i * piece;
final int endIndex = (i == threadCount - 1) ? len - startIndex - 1 : startIndex + piece;
MyTask task = new MyTask("MyTask##"+i, i, new EndListener(){
#Override
public void onEnd(int index, String name) {
Log.e("ThreadEND", "name = "+name);
reQueue(index);
}
}) {
#Override
public void execute() {
for(int index = startIndex; index < endIndex; ++index){
File file = new File(mFiles[index]);
InputStream is = null;
ByteArrayOutputStream os = null;
byte[] data = null;
try {
is = mContext.getAssets().open(path + File.separator + file.getName());
os = new ByteArrayOutputStream();
int count = 0;
byte[] buffer = new byte[1024];
while((count = is.read(buffer)) > 0){
os.write(buffer, 0, count);
}
os.flush();
data = os.toByteArray();
debug(getName(), index, path + File.separator + file.getName());
} catch (Exception e) {
e.printStackTrace();
} finally{
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if(data != null){
add(data);
}
}
}
};
mQueue[i] = task;
task.start();
}
}
private void debug(String who, int index, String name){
Log.e("MULTI LOADER DEBUG", "who = "+who+" , name = "+name+", index = "+index);
}
private void initialize(String path){
threadCount = getNumCores() * 2;
try {
mFiles = mContext.getAssets().list(path);
} catch (IOException e) {
e.printStackTrace();
}
}
private void add(byte[] data){
synchronized (fileContents) {
fileContents.add(data);
}
}
private void remove(byte[] data){
synchronized (fileContents) {
fileContents.remove(data);
}
}
public void clear(){
synchronized (fileContents) {
fileContents.clear();
}
}
private int getNumCores() {
class CpuFilter implements FileFilter {
#Override
public boolean accept(File pathname) {
if(Pattern.matches("cpu[0-9]+", pathname.getName())) {
return true;
}
return false;
}
}
try {
File dir = new File("/sys/devices/system/cpu/");
File[] files = dir.listFiles(new CpuFilter());
return files.length;
} catch(Exception e) {
return 1;
}
}
private abstract class MyTask extends Thread{
private EndListener listener;
private int index;
private MyTask() { }
public MyTask(String threadName, int index, EndListener listener) {
super(threadName);
this.index = index;
this.listener = listener;
}
public abstract void execute();
#Override
public void run() {
execute();
end();
}
public void end(){
listener.onEnd(index, getName());
}
public int getIndex(){
return index;
}
}
public interface TaskListener{
public void onTaskEnd();
}
public interface EndListener{
public void onEnd(int index, String name);
}
}
I writed a robotium test that runs a test on a apk file.
In this case i created the apk file in a previous android poroject, as the apk is still in a debug mode.
the test clicks and inserts data in the app.
as running it in emulator i get the error "Injecting to another application requires INJECT_EVENTS permission".
i tried every selution thst i finded in the internet, But to no avail.
Here is a list of the selutions i tried:
setting emulator on root.
making the test sleep for e few seconds in beginng of test.
adding to manifest:
<uses-permission android:name="android.permission.INJECT_EVENTS"/>
aslo adding this to manifest:
android:anyDensity="true"
adding in setUp function:
setActivityInitialTouchMode(true);
aslo adding this in setUp function:
KeyguardManager km =
(KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if (km.inKeyguardRestrictedInputMode())
{
KeyguardManager.KeyguardLock lock = km.newKeyguardLock("some_tag");
lock.disableKeyguard();
SystemClock.sleep(2000);
}
moved the app from data/appfolder to system aoo folder.
unlocked screen in code with:
mSolo.unlockScreen();
aslo unlocked with:
adb shell input keyevent 82
i am adding the code.
the code contains three classes, and the manifest:
class Main:
package genericTest.test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.content.Context;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.test.SingleLaunchActivityTestCase;
import android.util.Log;
import android.view.Display;
import android.view.View;
import com.robotium.solo.Solo;
#SuppressWarnings("rawtypes")
public class Main extends ActivityInstrumentationTestCase2 {
//public class Main extends SingleLaunchActivityTestCase {
//SingleLaunchActivityTestCase
private FunctonsForViews mFunctonsForViews;
private Random mRand;
private Solo mSolo;
//private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.goldtouch.ynet.ui.activities.SplashActivity";
private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.bignerdranch.android.criminalintent.CrimeListActivity";
//in Manifest: <!--android:targetPackage="com.bignerdranch.android.criminalintent"-->
//private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.mojang.minecraftpe.MainActivity";
//in Manifest: <!--android:targetPackage="com.mojang.minecraftpe"-->
private final int LIMIT_TIME = 300000;
private final int DELAY = 200;
private final int SCREEN_SIZE = 200;
private final int ERROR_COUNT_LIMIT = 10;
private final int CLICK_ON_LOOP_LIMIT = 20;
private final int WHAITING_FOR_VIEWS_LIMIT = 20;
private static Class launcherActivityClass;
private static int error_count = 0;
static {
try {
launcherActivityClass = Class
.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
#SuppressLint("NewApi")
#SuppressWarnings("unchecked")
public Main() throws ClassNotFoundException {
super(launcherActivityClass);
}
protected void setUp() throws Exception {
setActivityInitialTouchMode(true);
mSolo = new Solo(getInstrumentation(), getActivity());
Context context = getActivity();
int temp = 0;
KeyguardManager km =
(KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if (km.inKeyguardRestrictedInputMode())
{
KeyguardManager.KeyguardLock lock = km.newKeyguardLock("some_tag");
lock.disableKeyguard();
SystemClock.sleep(2000);
}
setActivityInitialTouchMode(true);
}
/*
* runs the test for the app.
*/
public void testMethod()
{
mFunctonsForViews = new FunctonsForViews(mSolo);
mSolo.sleep(10000);
mRand = new Random();
/*
* the test will take place in the loop, and will be limit in time.
* in every iteration it will get the vies in activity's, and run a test on a random view.
*/
for(int i=0 ;i < LIMIT_TIME ; i += DELAY)
{
mSolo.unlockScreen();
ArrayList Views = mSolo.getViews();
int arraySize = Views.size();
if (arraySize == 0)// now View in activity.
{
whenNoViewsInScreen(Views, arraySize);
}
if (arraySize != 0)
{
int ViewIndexInArray = mRand.nextInt(arraySize + 1);
if (ViewIndexInArray == arraySize)
{
mSolo.scrollDown();
}
else
{
View randomView = (View)(Views.get(ViewIndexInArray));
runTestOnOneView(randomView);
}
}
}
}
/*
* performing clicks onScreen()
*/
public void myClickOnScreen()
{
try {
mSolo.unlockScreen();
mSolo.clickOnScreen(mRand.nextInt(SCREEN_SIZE), mRand.nextInt(SCREEN_SIZE));
//mSolo.clickLongOnScreen(mRand.nextInt(SCREEN_SIZE), mRand.nextInt(SCREEN_SIZE));
} catch (Exception e) {
e.printStackTrace();
Log.e("in exception of clickOnScreen function.", "error_count=" + error_count);
if(error_count > ERROR_COUNT_LIMIT)
{
//goingBack();
error_count = 0;
}
//e.printStackTrace();
} catch (Error e2) {
e2.printStackTrace();
Log.e("in error of clickOnScreen function.", "error_count=" + error_count);
if(error_count > ERROR_COUNT_LIMIT)
{
//goingBack();
error_count = 0;
}
//e2.printStackTrace();
}
}
/*
* there is no Views available.
* we will try pressing on screen or the goBack function.
*/
public void whenNoViewsInScreen(ArrayList Views, int arraySize)
{
for (int j = 0; j < WHAITING_FOR_VIEWS_LIMIT; j++)
{
for (int k= 0; k < CLICK_ON_LOOP_LIMIT; k++)
{
myClickOnScreen();
}
Views = mSolo.getViews();
arraySize = Views.size();
if (arraySize != 0)
{
return;
}
mSolo.sleep(DELAY);
Views = mSolo.getViews();
arraySize = Views.size();
if (arraySize != 0)
{
return;
}
}
goingBack();
mSolo.sleep(DELAY);
return;
}
public void runTestOnOneView(View randomView)
{
String rawViewName = randomView.getClass().getName();
String viewName = parseRawViewName(rawViewName);
Log.i("ViewName", viewName);
//temp
/*if (viewName.contains("ActionBarContainer"))
{
return;
}*/
MyRunnable myRunnable = mFunctonsForViews.getMethodMap().get(viewName);
try{
if (myRunnable != null)
{
Log.e("myRunnable != null", viewName);
myRunnable.run((View)randomView);
}
else // view not in map.
{
boolean inMap = false;
Iterator it = mFunctonsForViews.getMethodMap().entrySet().iterator();
/*
* iterating in case the View is a version of one of View in map
* example:
* View is "CustomEditText", and map contains o view "EditText".
*/
while (it.hasNext())
{
Map.Entry pairs = (Map.Entry)it.next();
if ( viewName.contains((String)pairs.getKey()) )
{
inMap = true;
// next two lines changed
myRunnable = (MyRunnable)(pairs.getValue());
myRunnable.run((View)randomView);
break;
}
}
if (inMap == false)
{
mSolo.clickOnView((View)randomView);
}
error_count = 0;
}
}catch(Exception exception)
{
exception.printStackTrace();
Log.e("Exception click on view", viewName);
for (int i=0 ; i < CLICK_ON_LOOP_LIMIT; i++)
{
myClickOnScreen();
error_count ++;
if(error_count > ERROR_COUNT_LIMIT)
{
goingBack();
error_count = 0;
}
}
}catch(Error error)
{
error.printStackTrace();
Log.e("Error click on view ", viewName+ " " + error.toString());
for (int i=0 ; i < CLICK_ON_LOOP_LIMIT; i++)
{
myClickOnScreen();
error_count ++;
if(error_count > ERROR_COUNT_LIMIT)
{
goingBack();
error_count = 0;
}
}
}
mSolo.sleep(DELAY);
}
/*
* performs a goBack command surrounded with catch/try
*/
public void goingBack()
{
try {
mSolo.goBack();
} catch (Exception e) {
//Log.e("Exeption! ", "Can;t go back" );
e.printStackTrace();
} catch (Error e) {
//Log.e("Error! ", "Can;t go back" );
e.printStackTrace();
}
}
/*
* extract the name of View from raw View name.
* example:
* raw View name: android.widget.TextView
* raw View name:TextView
*/
public String parseRawViewName(String rawViewName)
{
if (rawViewName.contains(" "))
{
String [] array = rawViewName.split(" ");
rawViewName = array [0];
}
if (rawViewName.contains(".") || rawViewName.contains("$"))
{
String [] array = rawViewName.split("\\.|$");
Log.i("array length:", ""+ array.length);
rawViewName = array [array.length-1];
}
return rawViewName;
}
public void tearDown() throws Exception {
mSolo.finishOpenedActivities();
//super.tearDown();
}
}
class FunctonsForViews:
package genericTest.test;
import java.lang.reflect.*;
import java.util.*;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.TimePicker;
import com.robotium.solo.Solo;
/*
* contains the functions and parameters running for every View.
*/
public class FunctonsForViews {
private Map<String, MyRunnable> mMethodMap;
private Solo mSolo;
private Random mRand = new Random();
private final int LIST_TEST_FUNCTIONS = 4;
private final String TAG = "FunctonsForViews";
private final String [] editTextMailInput =
{"example#gmail.com", "secondExample#gmail.com", "erongFormat","123"};
private final String [] editTextPasswordInput =
{"0987654321", "0987654321a", "12","iioo", "ui9"};
private final String [] editTextNameInput =
{"yoav", "567", "ran","iioott", "iioottrr", "iioottrraaqqhh", "iioottrraaqqhh23"};
private final String [] editTextTelephoneInput =
{"078123456", "078123456a", "dan","4675", "123"};
//getter
public Map<String, MyRunnable> getMethodMap()
{
return mMethodMap;
}
/*
* initials the HashMap mMethodMap, and insert the fitting function for handling every View in activity
*/
public FunctonsForViews(Solo solo)
{
mSolo = solo ;
mMethodMap = new HashMap<String, MyRunnable>();
try {
mMethodMap.put("EditText", new MyRunnable() {
public void run(View view) { MyEnterText(view); }
});
/*
mMethodMap.put("CustomEditText", new MyRunnable() {
public void run(View view) { MyEnterText(view); }
});*/
mMethodMap.put("ProgressBar", new MyRunnable() {
public void run(View view) { MySetProgressBar(view); }
});
mMethodMap.put("TimePicker", new MyRunnable() {
public void run(View view) { MySetTimePicker(view); }
});
mMethodMap.put("DatePicker", new MyRunnable() {
public void run(View view) { MySetDatePicker(view); }
});
mMethodMap.put("ListView", new MyRunnable() {
public void run(View view) { MyListTest(view); }
});
/*
mMethodMap.put("e", new MyRunnable() {
public void run(View view) { doNuthing(view); }
});
*/
} catch (Exception e) {
Log.i(TAG, "Cant put in map");
e.printStackTrace();
}
}
/*
* sets random values in the TimePicker View
*/
public void MySetTimePicker(View view)
{
int hour = mRand.nextInt(24);
int minute = mRand.nextInt(60);
mSolo.setTimePicker((android.widget.TimePicker)view, hour, minute);
}
/*
* sets random values in the DatePicker View
*/
public void MySetDatePicker(View view)
{
int year = mRand.nextInt((2020 - 1900) ) + 1900;
int month = mRand.nextInt(12);
int dayOfMonth = mRand.nextInt((31 - 1) ) + 1;
mSolo.setDatePicker((android.widget.DatePicker)view, year, month, dayOfMonth);
}
/*
* sets random values in the ProgressBar View
*/
public void MySetProgressBar(View view)
{
ProgressBar progressBar = (ProgressBar)view;
mSolo.setProgressBar(progressBar, mRand.nextInt(progressBar.getMax()));
}
/*
* calls a random ViewList Solo function
*/
public void MyListTest(View view)
{
int function = mRand.nextInt(LIST_TEST_FUNCTIONS );
switch (function)
{
case 0:
if (((((ListView)view).getLastVisiblePosition()
- ((ListView)view).getFirstVisiblePosition()) + 1) >0)
{
mSolo.clickInList(mRand.nextInt(((ListView)view).getLastVisiblePosition()
- ((ListView)view).getFirstVisiblePosition()) + 1);
}
break;
case 1:
if (((((ListView)view).getLastVisiblePosition()
- ((ListView)view).getFirstVisiblePosition()) + 1) >0)
{
//mSolo.clickLongInList(mRand.nextInt(((ListView)view).getLastVisiblePosition()
//- ((ListView)view).getFirstVisiblePosition()) + 1);
mSolo.clickInList(mRand.nextInt(((ListView)view).getLastVisiblePosition()
- ((ListView)view).getFirstVisiblePosition()) + 1);
}
break;
case 2:
mSolo.scrollListToBottom((ListView)view) ;
break;
default:
mSolo.scrollListToTop((ListView)view) ;
break;
}
}
/*
* sets the text of a EditText View
*/
public void MyEnterText(View view)
{
mSolo.clearEditText((android.widget.EditText)view);
mSolo.enterText((android.widget.EditText)view, getStringForEditTextInput(view));
}
/*
* return a string to be use to set in EditText View.
* the specific string will be choose randomly.
*/
public String getStringForEditTextInput(View view)
{
ArrayList Views = mSolo.getViews();
String EditTextInput = null;
int index = Views.indexOf(view);
for (int i = index - 1; i> index - 4; i--)
{
if (Views.get(i).getClass().getName() == "TextView" )
{
String textViewText = ((TextView)Views.get(i)).getText().toString().toLowerCase();
if(textViewText.contains("mail"))
{
EditTextInput = editTextMailInput[mRand.nextInt(editTextMailInput.length) ];
}
else if(textViewText.contains("password"))
{
EditTextInput = editTextPasswordInput[mRand.nextInt(editTextPasswordInput.length) ];
}
else if(textViewText.contains("telephone"))
{
EditTextInput = editTextTelephoneInput[mRand.nextInt(editTextTelephoneInput.length) ];
}
return EditTextInput;
}
}
EditTextInput = editTextNameInput[mRand.nextInt(editTextNameInput.length) ];
return EditTextInput;
}
}
interface MyRunnable:
package genericTest.test;
import android.view.View;
/*
* used for storing function HashMap
*/
public interface MyRunnable {
public void run(View view);
}
manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="genericTest.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.INJECT_EVENTS"/>
android:anyDensity=”true"
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.bignerdranch.android.criminalintent"/>
/>
<supports-screens
android:resizeable="true"
android:smallScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:normalScreens="true"
android:anyDensity="true"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<uses-library android:name="android.test.runner" />
</application>
</manifest>
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am having a problem with a task that shows live content from a site.
I have been playing around with this code for a while and playing around with the status but I can't seem to get it to work correctly.
The only solution I have been able to come up with so far is completely disable orientation changes, but I would prefer not to do that if possible.
Here is the Stack Trace:
STACK_TRACE = java.lang.IllegalArgumentException: View not attached to window manager
at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:653)
at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:349)
at android.view.WindowManagerImpl$CompatModeWrapper.removeView(WindowManagerImpl.java:160)
at android.app.Dialog.dismissDialog(Dialog.java:319)
at android.app.Dialog.dismiss(Dialog.java:302)
at cl.cromer.tronwell.concepcion.Progress.dismiss(Progress.java:72)
at cl.cromer.tronwell.concepcion.AdditionalMaterial.databaseLoaded(AdditionalMaterial.java:149)
at cl.cromer.tronwell.concepcion.AdditionalMaterial.access$13(AdditionalMaterial.java:122)
at cl.cromer.tronwell.concepcion.AdditionalMaterial$1$1.run(AdditionalMaterial.java:73)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5031)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
at dalvik.system.NativeStart.main(Native Method)
Here is my code for the class that is crashing:
package cl.cromer.tronwell.concepcion;
import java.util.Calendar;
import java.util.HashMap;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import cl.cromer.tronwell.concepcion.DBSchema.DBAdditionalMaterial;
import cl.cromer.tronwell.concepcion.DBSchema.DBAdditionalMaterialGroups;
import cl.cromer.tronwell.concepcion.Files.Download;
public class AdditionalMaterial extends ActionBarActivity implements ListenerXML, ListenerDownload, ListenerAsync {
private final static String URL = "action=downloads";
private XMLParser xmlParser;
private Progress progress = null;
// Parsers
private SQLParser sqlParser;
private Handler threadHandler = new Handler();
// The database
private SQLiteDatabase tronDB;
private int downloadId = 0;
private boolean downloadAll = false;
private int downloadCount = 1;
private int firstDownloadAvailable = 0;
private String fileName;
private Files files = new Files();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("debug", "onCreate");
setContentView(R.layout.activity_additional_material);
//progress = new Progress();
//progress.show(this, this, false);
sqlParser = new SQLParser(this);
new Thread(new Runnable() {
public void run() {
tronDB = sqlParser.getWritableDatabase();
threadHandler.post(new Runnable() {
public void run() {
databaseLoaded();
}
});
}
}).start();
}
#Override
protected void onStart() {
super.onStart();
Log.d("debug", "onStart");
}
#Override
protected void onRestart() {
super.onRestart();
Log.d("debug", "onRestart");
}
#Override
protected void onResume() {
super.onResume();
progress = new Progress();
progress.show(this, this, false);
Log.d("debug", "onResume");
}
#Override
protected void onStop() {
super.onStop();
Log.d("debug", "onStop");
}
#Override
protected void onDestroy() {
super.onDestroy();
progress = null;
Log.d("debug", "onDestroy");
}
#Override
public void onPause() {
super.onPause();
Log.d("debug", "onDestroy");
}
private void databaseLoaded() {
SharedPreferences settings = getSharedPreferences(Settings.PREFERENCES, MODE_PRIVATE);
long materialDate = settings.getLong(Settings.MATERIAL_DATE, Settings.MATERIAL_DATE_DEFAULT);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
long currentDate = calendar.getTimeInMillis();
if (currentDate > materialDate ) {
// Update the database
String rut = settings.getString(Settings.RUT, Settings.RUT_DEFAULT);
String password = settings.getString(Settings.PASSWORD, Settings.PASSWORD_DEFAULT);
HashMap<String, String> postData = new HashMap<String, String>();
postData.put("rut", rut);
postData.put("pass", password);
xmlParser = new XMLParser(this, postData);
xmlParser.fetchListener = this; // Tell the XMLParser that this activity has the listener
xmlParser.execute(MainActivity.URL + URL);
}
else {
// Material does not need to be updated, just show what is in the database
if (progress != null && progress.isShowing()) {
progress.dismiss();
}
ShowContent showContent = new ShowContent(this);
showContent.asyncListener = this; // Tell the task that this class is listening
showContent.execute();
}
}
private void fetchFinished(HashMap<String, HashMap<String, String>> xmlData) {
// Let's put the groups in the database
HashMap<String, String> xmlHash = xmlData.get("1");
String groups = xmlHash.get("groups");
for (int i = 1; i <= Integer.valueOf(groups); i++) {
ContentValues values = new ContentValues();
values.put(DBAdditionalMaterialGroups.COLUMN_ID, String.valueOf(i));
values.put(DBAdditionalMaterialGroups.COLUMN_NAME, xmlHash.get("group" + String.valueOf(i)));
tronDB.replace(
DBAdditionalMaterialGroups.TABLE_NAME,
null,
values);
}
// Now the material
for (int i = 2; i <= xmlData.size() - 1; i++) {
xmlHash = xmlData.get(String.valueOf(i));
ContentValues values = new ContentValues();
values.put(DBAdditionalMaterial.COLUMN_ID, xmlHash.get("id"));
values.put(DBAdditionalMaterial.COLUMN_NAME, xmlHash.get("title"));
values.put(DBAdditionalMaterial.COLUMN_GROUP, xmlHash.get("group"));
values.put(DBAdditionalMaterial.COLUMN_TYPE, xmlHash.get("type"));
values.put(DBAdditionalMaterial.COLUMN_URL1, xmlHash.get("url1"));
values.put(DBAdditionalMaterial.COLUMN_URL2, xmlHash.get("url2"));
tronDB.replace(
DBAdditionalMaterial.TABLE_NAME,
null,
values);
}
SharedPreferences settings = getSharedPreferences(Settings.PREFERENCES, MODE_PRIVATE);
SharedPreferences.Editor settingsEditor = settings.edit();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
long currentDate = calendar.getTimeInMillis();
settingsEditor.putLong(Settings.MATERIAL_DATE, currentDate);
settingsEditor.commit();
progress.dismiss();
ShowContent showContent = new ShowContent(this);
showContent.asyncListener = this; // Tell the task that this class is listening
showContent.execute();
}
#TargetApi(Build.VERSION_CODES.FROYO)
protected class ShowContent extends AsyncTask<String, View, Void> {
private Context context;
private PowerManager.WakeLock wakeLock;
protected ListenerAsync asyncListener = null; // This needs to be set from the parent activity
private LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linear_layout);
protected ShowContent(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// Let's make sure the CPU doesn't go to sleep
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
wakeLock.acquire();
}
#SuppressLint("InflateParams")
#Override
protected Void doInBackground(String... passedInfo) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View categoryView;
View downloadView;
View seperatorView;
TextView textView = new TextView(context);
ImageButton imageButton = new ImageButton(context);
Cursor cursorMaterialGroups = tronDB.query(
DBAdditionalMaterialGroups.TABLE_NAME,
DBAdditionalMaterialGroups.ALL_COLUMNS,
null,
null,
null,
null,
DBAdditionalMaterialGroups.COLUMN_ID + " ASC",
null);
while (cursorMaterialGroups.moveToNext()) {
// Create a group TextView by inflating a layout
categoryView = inflater.inflate(R.layout.additional_material_category, null);
textView = (TextView) categoryView;
textView.setText(cursorMaterialGroups.getString(cursorMaterialGroups.getColumnIndex(DBAdditionalMaterialGroups.COLUMN_NAME)));
publishProgress(textView);
// Now to get the downloads from the group
Cursor cursorMaterial = tronDB.query(DBAdditionalMaterial.TABLE_NAME,
DBAdditionalMaterial.ALL_COLUMNS,
DBAdditionalMaterial.COLUMN_GROUP + "=" + cursorMaterialGroups.getString(cursorMaterialGroups.getColumnIndex(DBAdditionalMaterialGroups.COLUMN_ID)),
null,
null,
null,
DBAdditionalMaterial.COLUMN_ID + " ASC",
null);
downloadCount += cursorMaterial.getCount();
while (cursorMaterial.moveToNext()) {
downloadView = inflater.inflate(R.layout.additional_material_download, null);
// Download title
textView = (TextView) downloadView.findViewById(R.id.download_title);
textView.setText(cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_NAME)));
// Download/play button
imageButton = (ImageButton) downloadView.findViewById(R.id.download_button);
imageButton.setId(Integer.valueOf(cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_ID))));
String fileName = null;
if (cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_TYPE)).equals("pdf")) {
fileName = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_ID)) + ".pdf";
}
else {
fileName = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_ID)) + ".mp3";
}
Drawable drawable = getResources().getDrawable(R.drawable.ic_action_play);
if (!files.fileExists(context, fileName)) {
if (firstDownloadAvailable == 0) {
firstDownloadAvailable = imageButton.getId();
}
drawable = getResources().getDrawable(R.drawable.ic_action_save);
imageButton.setImageDrawable(drawable);
imageButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
downloadId = view.getId();
download();
}
});
}
else {
imageButton.setImageDrawable(drawable);
imageButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String contentId = String.valueOf(view.getId());
openContent(contentId);
}
});
}
publishProgress(downloadView);
if (!cursorMaterial.isLast()) {
seperatorView = inflater.inflate(R.layout.additional_material_seperator, null);
publishProgress(seperatorView);
}
}
cursorMaterial.close();
}
// Other
categoryView = inflater.inflate(R.layout.additional_material_category, null);
textView = (TextView) categoryView;
textView.setText("OTHER");
publishProgress(textView);
// Download all
downloadView = inflater.inflate(R.layout.additional_material_download, null);
// Download title
textView = (TextView) downloadView.findViewById(R.id.download_title);
textView.setText("Download all material");
// Download/play button
imageButton = (ImageButton) downloadView.findViewById(R.id.download_button);
imageButton.setId(1);
Drawable drawable = getResources().getDrawable(R.drawable.ic_action_play);
drawable = getResources().getDrawable(R.drawable.ic_action_save);
imageButton.setImageDrawable(drawable);
imageButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
downloadId = firstDownloadAvailable;
downloadAll = true;
download();
}
});
publishProgress(downloadView);
cursorMaterialGroups.close();
return null;
}
#Override
protected void onProgressUpdate(View... view) {
linearLayout.addView(view[0]);
}
#Override
protected void onPostExecute(Void result) {
wakeLock.release();
if (asyncListener != null) {
// Call the listener if one is set
asyncListener.onAsyncComplete();
}
}
}
private void download() {
progress.show(this, this, true);
Files files = new Files();
// Check if the memory card can be written to
if (files.isWriteable()) {
Cursor cursorMaterial = tronDB.query(DBAdditionalMaterial.TABLE_NAME,
DBAdditionalMaterial.ALL_COLUMNS,
DBAdditionalMaterial.COLUMN_ID + "=" + String.valueOf(downloadId),
null,
null,
null,
null,
"1");
cursorMaterial.moveToFirst();
String title = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_NAME));
String type = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_TYPE));
String url1 = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_URL1));
String url2 = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_URL2));
cursorMaterial.close();
if (type.equals("pdf")) {
fileName = String.valueOf(downloadId) + ".pdf";
}
else {
fileName = String.valueOf(downloadId) + ".mp3";
}
// Change the message in the downloading prompt
progress.setMessage(getString(R.string.general_downloading) + " " + title);
SharedPreferences settings = getSharedPreferences(Settings.PREFERENCES, MODE_PRIVATE);
String rut = settings.getString(Settings.RUT, Settings.RUT_DEFAULT);
String url = url1 + rut + url2;
url = url.replace(" ", "%20");
final Download download = files.new Download(this, fileName, progress);
download.downloadListener = this;
download.execute(url);
progress.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
downloadAll = false;
download.cancel(true);
}
});
}
else {
progress.dismiss();
Toast.makeText(this, getString(R.string.general_no_memory), Toast.LENGTH_SHORT).show();
}
}
private void openContent(String contentId) {
Cursor cursorMaterial = tronDB.query(DBAdditionalMaterial.TABLE_NAME,
DBAdditionalMaterial.ALL_COLUMNS,
DBAdditionalMaterial.COLUMN_ID + "=" + contentId,
null,
null,
null,
null,
"1");
cursorMaterial.moveToFirst();
String type = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_TYPE));
cursorMaterial.close();
String fileName = "";
String mimeType = "";
if (type.equals("pdf")) {
fileName = contentId + ".pdf";
mimeType = "application/pdf";
}
else {
fileName = contentId + ".mp3";
mimeType = "audio/mp3";
}
files.openFile(this, fileName, mimeType);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (intent.getBooleanExtra(ConnectionFailed.RETRY, false)) {
// Failed, let's try the connection again
SharedPreferences settings = getSharedPreferences(Settings.PREFERENCES, MODE_PRIVATE);
String rut = settings.getString(Settings.RUT, Settings.RUT_DEFAULT);
String password = settings.getString(Settings.PASSWORD, Settings.PASSWORD_DEFAULT);
HashMap<String, String> postData = new HashMap<String, String>();
postData.put("rut", rut);
postData.put("pass", password);
xmlParser = new XMLParser(this, postData);
xmlParser.fetchListener = this; // Tell the XMLParser that this activity has the listener
xmlParser.execute(MainActivity.URL + URL);
}
}
// This is the listener for the xml
public void onFetchComplete(String xml) {
if (xml == null) {
progress.dismiss();
// Failed to fetch xml, either a server error or an internet connection problem
Intent intent = new Intent(this, ConnectionFailed.class);
startActivityForResult(intent, 1);
}
else {
HashMap<String, HashMap<String, String>> xmlHash = xmlParser.parseXML(xml);
new User().checkUserValidation(xmlHash.get("0"));
fetchFinished(xmlHash);
}
}
// This is the listener for the download
public void onDownloadComplete(boolean result) {
progress.dismiss();
if (!result) {
Toast.makeText(this, getString(R.string.general_failed_download), Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(this, getString(R.string.general_download_complete), Toast.LENGTH_SHORT).show();
Drawable drawable = getResources().getDrawable(R.drawable.ic_action_play);
ImageButton buttonView = (ImageButton) findViewById(downloadId);
buttonView.setImageDrawable(drawable);
buttonView.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String contentId = String.valueOf(view.getId());
openContent(contentId);
}
});
if (downloadAll) {
while (downloadCount >= downloadId) {
downloadId++;
Cursor cursorMaterial = tronDB.query(DBAdditionalMaterial.TABLE_NAME,
DBAdditionalMaterial.ALL_COLUMNS,
DBAdditionalMaterial.COLUMN_ID + "=" + String.valueOf(downloadId),
null,
null,
null,
null,
"1");
cursorMaterial.moveToFirst();
String type = cursorMaterial.getString(cursorMaterial.getColumnIndex(DBAdditionalMaterial.COLUMN_TYPE));
cursorMaterial.close();
if (type.equals("pdf")) {
fileName = String.valueOf(downloadId) + ".pdf";
}
else {
fileName = String.valueOf(downloadId) + ".mp3";
}
if (!files.fileExists(this, fileName)) {
download();
break;
}
}
if (downloadCount == downloadId) {
// The last one downloaded we can now stop the process
downloadAll = false;
}
}
}
}
// This is the listener for the Async
public void onAsyncComplete() {
progress.dismiss();
}
}
Here is the code for my progress bar:
package cl.cromer.tronwell.concepcion;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
public final class Progress {
protected ProgressDialog progressBar = null;
private int oldOrientation = -1; // Orientation not set
private Activity activity;
protected void show(Context context, Activity activity, boolean cancelable) {
this.activity = activity;
// Disable rotation while we are loading something
oldOrientation = activity.getRequestedOrientation();
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
if (progressBar != null && progressBar.isShowing()) {
activity.setRequestedOrientation(oldOrientation);
progressBar.dismiss();
}
progressBar = new ProgressDialog(context);
progressBar.setCancelable(cancelable);
if (!cancelable) {
progressBar.setMessage(context.getString(R.string.general_loading));
progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
}
else {
progressBar.setIndeterminate(true);
progressBar.setCanceledOnTouchOutside(false);
progressBar.setMessage(context.getString(R.string.general_downloading));
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
}
progressBar.setProgress(0);
progressBar.setMax(100);
progressBar.show();
}
protected void setMessage(String message) {
progressBar.setMessage(message);
}
protected void setIndeterminate(boolean indeterminate) {
progressBar.setIndeterminate(indeterminate);
}
protected void setProgress(int progress) {
progressBar.setProgress(progress);
}
protected void setOnCancelListener(DialogInterface.OnCancelListener listener) {
progressBar.setOnCancelListener(listener);
}
protected boolean isShowing() {
if (progressBar.isShowing()) {
return true;
}
return false;
}
protected void dismiss() {
// Turn rotation back to it's previous state
activity.setRequestedOrientation(oldOrientation);
if (progressBar != null && progressBar.isShowing()) {
progressBar.dismiss();
}
}
}
Check answer of this question Answer
I think you facing same issue
Check this one as well Answer 2
What i am doing is drawing application and there are two function needed for this project is the undo and redo .. so i need to save a list of previous drawing after each time the user draw and pull up his finger from the screen ..
This is the code when saving previous drawing
public void saveState() {
State mUndoState = new State();
saveState(mSurface.getBitmap(), mUndoState);
}
private void saveState(Bitmap bitmap, State state) {
state.mBuffer = new byte[bitmap.getRowBytes() * bitmap.getHeight()];
Buffer byteBuffer = ByteBuffer.wrap(state.mBuffer);
bitmap.copyPixelsToBuffer(byteBuffer);
mListUndoState.add(state);
System.out.println("Size now: " + (mListUndoState.size() - 1));
mListRedoState.clear();
mListRedoState.add(state);
// StylesFactory.saveState(state.stylesState);
}
private static class State {
byte[] mBuffer = null;
// final HashMap<Integer, Object> stylesState = new HashMap<Integer,
// Object>();
}
The problem is android devices only have 16 MB of heap memory .. what is the best way to deal with this issue? .. i can only save it to ListUndoState 7 to 10 times and then i got out of memory exception .. i want to get unlimited undo action or at least not less then 50 times.
Here is the full class that save the previous drawing for undo and redo.
package com.appshouse.drawgram.utli;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Bitmap;
public class HistoryHelper {
private final Surface mSurface;
private List<State> mListUndoState = new ArrayList<State>();
private List<State> mListRedoState = new ArrayList<State>();
public HistoryHelper(Surface surface) {
mSurface = surface;
}
public void undo() {
int length = mListUndoState.size() - 1;
if (length <= 0) {
System.out.println("no element is list");
return;
}
System.out.println("history undo size: " + length);
restoreState(mSurface.getBitmap(), mListUndoState.get(length - 1));
mListRedoState.add(mListUndoState.get(length));
mListUndoState.remove(length);
}
public void redo() {
int length = mListRedoState.size() - 1;
if (length <= 0) {
System.out.println("no element is list");
return;
}
System.out.println("history undo size: " + length);
restoreState(mSurface.getBitmap(), mListRedoState.get(length));
mListUndoState.add(mListRedoState.get(length));
mListRedoState.remove(length);
}
private void restoreState(Bitmap bitmap, State state) {
Buffer byteBuffer = ByteBuffer.wrap(state.mBuffer);
bitmap.copyPixelsFromBuffer(byteBuffer);
// StylesFactory.restoreState(state.stylesState);
}
public void saveState() {
State mUndoState = new State();
saveState(mSurface.getBitmap(), mUndoState);
}
private void saveState(Bitmap bitmap, State state) {
state.mBuffer = new byte[bitmap.getRowBytes() * bitmap.getHeight()];
Buffer byteBuffer = ByteBuffer.wrap(state.mBuffer);
bitmap.copyPixelsToBuffer(byteBuffer);
mListUndoState.add(state);
System.out.println("Size now: " + (mListUndoState.size() - 1));
mListRedoState.clear();
mListRedoState.add(state);
// StylesFactory.saveState(state.stylesState);
}
private static class State {
byte[] mBuffer = null;
// final HashMap<Integer, Object> stylesState = new HashMap<Integer,
// Object>();
}
}
As hieuxit suggest i save the bitmap in file-cache to get ride of this problem but i don't know if this is the best solution .. so if anyone got better solution please provide it to me.
Here is what i change in the previous class
package com.appshouse.drawgram.utli;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.widget.Toast;
public class HistoryHelper {
private final Surface mSurface;
int undoAvailable = 0;
int redoAvailable = 0;
Context context;
public HistoryHelper(Context c, Surface surface) {
mSurface = surface;
context = c;
}
public void undo() {
if (undoAvailable > 1) {
undoAvailable--;
new LoadRestoreState().execute();
redoAvailable ++;
} else {
Toast.makeText(context, "End of Undo Data", Toast.LENGTH_LONG)
.show();
}
}
public void redo() {
if(redoAvailable >= 1)
{
undoAvailable ++;
new LoadRestoreState().execute();
redoAvailable --;
}else
{
Toast.makeText(context, "End of Redo Data", Toast.LENGTH_LONG)
.show();
}
}
public void saveState() {
new LoadSaveState().execute(mSurface.getBitmap());
}
private class LoadSaveState extends AsyncTask<Bitmap, Void, Void>
{
#Override
protected Void doInBackground(Bitmap... params) {
undoAvailable++;
FileCache fileCache = new FileCache(context, String.valueOf(undoAvailable));
String str_buffer = Common.getStringDrawing(params[0]);
fileCache.writeFile(str_buffer);
redoAvailable = 0;
return null;
}
}
private class LoadRestoreState extends AsyncTask<Void , Void, Void>
{
#Override
protected Void doInBackground(Void... params) {
FileCache getFileChach = new FileCache(context,
String.valueOf(undoAvailable));
String image_str = getFileChach.readFile();
Bitmap drawing = Common.getBitmapFromString(image_str);
byte[] buffer = new byte[drawing.getRowBytes()
* drawing.getHeight()];
Buffer byteBuffer = ByteBuffer.wrap(buffer);
drawing.copyPixelsToBuffer(byteBuffer);
byteBuffer = ByteBuffer.wrap(buffer);
mSurface.getBitmap().copyPixelsFromBuffer(byteBuffer);
return null;
}
}
}
Where the FileCache class is:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import android.content.Context;
public class FileCache {
private File cacheDir;
private File TempFile;
public FileCache(Context context, String Filename) {
cacheDir = context.getCacheDir();
if (!cacheDir.exists())
cacheDir.mkdirs();
TempFile = new File(cacheDir.getPath(), Filename);
}
public void writeFile(String buffer)
{
FileWriter writer = null;
try {
writer = new FileWriter(TempFile);
writer.write(buffer);
System.out.println(TempFile + " File - data: " + buffer.toString()
);
writer.close();
} catch (IOException e) {
}
}
public String readFile() {
String strLine = "";
StringBuilder text = new StringBuilder();
try {
FileReader fileReader = new FileReader(TempFile);
BufferedReader bufferReader = new BufferedReader(fileReader);
while ((strLine = bufferReader.readLine()) != null) {
text.append(strLine + "\n");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("get text String: "+text.toString());
return text.toString();
}
public void clear() {
File[] files = cacheDir.listFiles();
if (files == null)
return;
for (File f : files)
f.delete();
}
}
And Here is Two Function that i created in Common class:
public static String getStringDrawing(Bitmap bm) {
String image_str = "";
ByteArrayOutputStream stream = new ByteArrayOutputStream();
byte[] byte_arr;
bm.compress(Bitmap.CompressFormat.PNG, 90, stream);
byte_arr = stream.toByteArray();
image_str = Base64.encodeBytes(byte_arr);
return image_str;
}
public static Bitmap getBitmapFromString(String img_str)
{
Bitmap bmImg = null;
try {
byte[] encodeByte = null;
encodeByte = Base64.decode(img_str);
bmImg = BitmapFactory.decodeByteArray(encodeByte, 0,
encodeByte.length);
bmImg = Bitmap.createBitmap(bmImg);
} catch (Exception e) {
e.printStackTrace();
}
return bmImg;
}
of-course you need to download base64 class for converting the image to string and vice versa
In my app, I have to display PDF file from sdcard in android. The app uses tab functionality so I have used fragments in my app. So how to display pdf file inside fragments?
I have used pdfviewer.jar, but I am not able to display inside fragments, it only works in activity.
And another question is I want to display pdf with multi-zoom and vertical page scrolling to see next/previous pages, not by manually clicking on zoom icon and arrow icon to see next page which is used in pdfviewer.jar.
I am giving the full code below of that changed fragment. I did it 3 years back and that time Sherlock library was used. I think now you have to replace that by appcompat library.
package net.sf.andpdf.pdfviewer;
import java.io.*;
import java.nio.channels.FileChannel;
import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.*;
import android.widget.ImageView;
import android.widget.TextView;
import net.sf.andpdf.nio.ByteBuffer;
import net.sf.andpdf.pdfviewer.gui.TouchImageView;
import net.sf.andpdf.refs.HardReference;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFImage;
import com.sun.pdfview.PDFPage;
import com.sun.pdfview.PDFPaint;
import com.sun.pdfview.decrypt.PDFAuthenticationFailureException;
import com.sun.pdfview.decrypt.PDFPassword;
import com.sun.pdfview.font.PDFFont;
public class PdfViewerFragment extends SherlockFragment {
private static final int STARTPAGE = 1;
private static float STARTZOOM = 1f;
private static final String TAG = "PDFVIEWER";
private static final String FTAG = "PDFVIEWERFRG";
public static final String EXTRA_PDFFILENAME = "net.sf.andpdf.extra.PDFFILENAME";
public static final String EXTRA_SHOWIMAGES = "net.sf.andpdf.extra.SHOWIMAGES";
public static final String EXTRA_ANTIALIAS = "net.sf.andpdf.extra.ANTIALIAS";
public static final String EXTRA_USEFONTSUBSTITUTION = "net.sf.andpdf.extra.USEFONTSUBSTITUTION";
public static final String EXTRA_KEEPCACHES = "net.sf.andpdf.extra.KEEPCACHES";
public static final boolean DEFAULTSHOWIMAGES = true;
public static final boolean DEFAULTANTIALIAS = true;
public static final boolean DEFAULTUSEFONTSUBSTITUTION = false;
public static final boolean DEFAULTKEEPCACHES = true;
private String pdffilename;
private PDFFile mPdfFile;
private int mPage;
private float mZoom;
private File mTmpFile;
private ProgressDialog progress;
private TextView tv_page_no;
String imgFileName;
private ImageView rightArrow;
private ImageView leftArrow;
private PDFPage mPdfPage;
private Thread backgroundThread;
private Activity activity;
TouchImageView tiv;
#Override
public void onAttach(Activity activity) {
Log.i(FTAG, "PDFFragment.onAttatch");
this.activity = activity;
super.onAttach(activity);
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Display display = activity.getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
if(activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE )
{
STARTZOOM = (1f*width)/800.0f;
}
else
{
STARTZOOM = (1f*height)/800.0f;
}
Log.i(FTAG, "PDFFragment: onCreate");
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i(FTAG, "PDFFragment: onCreateView");
View docView = inflater.inflate(R.layout.doc_viewer, container, false);
setRetainInstance(true);
boolean showImages = activity.getIntent().getBooleanExtra(PdfViewerFragment.EXTRA_SHOWIMAGES, PdfViewerFragment.DEFAULTSHOWIMAGES);
PDFImage.sShowImages = showImages;
boolean antiAlias = activity.getIntent().getBooleanExtra(PdfViewerFragment.EXTRA_ANTIALIAS, PdfViewerFragment.DEFAULTANTIALIAS);
PDFPaint.s_doAntiAlias = antiAlias;
boolean useFontSubstitution = activity.getIntent().getBooleanExtra(PdfViewerFragment.EXTRA_USEFONTSUBSTITUTION, PdfViewerFragment.DEFAULTUSEFONTSUBSTITUTION);
PDFFont.sUseFontSubstitution= useFontSubstitution;
boolean keepCaches = activity.getIntent().getBooleanExtra(PdfViewerFragment.EXTRA_KEEPCACHES, PdfViewerFragment.DEFAULTKEEPCACHES);
HardReference.sKeepCaches= keepCaches;
Bundle args = getArguments();
if (args != null) {
Log.i(FTAG, "Args Value: "+args.getString(EXTRA_PDFFILENAME));
pdffilename = args.getString(EXTRA_PDFFILENAME);;
} else {
// TODO: open a default document
pdffilename = "/mnt/sdcard/documents/3.pdf";
}
tiv = (TouchImageView) docView.findViewById(R.id.imageView);
leftArrow = (ImageView) docView.findViewById(R.id.leftArrow);
rightArrow = (ImageView) docView.findViewById(R.id.rightArrow);
leftArrow.setVisibility(View.GONE);
rightArrow.setVisibility(View.GONE);
if (pdffilename == null)
{
pdffilename = "No file selected";
}
else if(pdffilename.contains(".pdf"))
{
imgFileName= pdffilename.substring(0, pdffilename.lastIndexOf("."))+"_1.jpg";
mPage = STARTPAGE;
mZoom = STARTZOOM;
progress = ProgressDialog.show(activity, "Loading", "Loading PDF Page", true, true);
leftArrow.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
prevPage();
}
});
rightArrow.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
nextPage();
}
});
tv_page_no = (TextView) docView.findViewById(R.id.navigationText);
tiv.setParent(this);
setContent(null);
}
else if(pdffilename.contains(".jpg") || pdffilename.contains(".jpeg") || pdffilename.contains(".png") || pdffilename.contains(".gif") || pdffilename.contains(".bmp"))
{
imgFileName = pdffilename;
tiv.setImageLocation(imgFileName);
}
else
{
pdffilename = "Invalid file extension";
}
return docView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
Log.i(FTAG, "PDFFragment: onViewCreated");
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i(FTAG, "PDFFragment: onActivityCreated");
}
#Override
public void onStart() {
Log.i(FTAG, "PDFFragment.onStart");
super.onStart();
//Bundle args = getArguments();
}
#Override
public void onResume() {
Log.i(FTAG, "PDFFragment.onResume");
super.onResume();
}
#Override
public void onPause() {
Log.i(FTAG, "PDFFragment.onPause");
super.onPause();
}
#Override
public void onSaveInstanceState(Bundle outState) {
Log.i(FTAG, "PDFFragment.onSaveInstanceState");
super.onSaveInstanceState(outState);
}
#Override
public void onStop() {
Log.i(FTAG, "PDFFragment.onStop");
super.onStop();
}
#Override
public void onDestroyView() {
Log.i(FTAG, "PDFFragment.onDestroyView");
super.onDestroyView();
}
#Override
public void onDestroy() {
Log.i(FTAG, "PDFFragment.onDestroy");
super.onDestroy();
if (mTmpFile != null) {
mTmpFile.delete();
mTmpFile = null;
}
}
#Override
public void onDetach() {
Log.i(FTAG, "PDFFragment.onDetach");
super.onDetach();
}
private boolean setContent(String password) {
try {
parsePDF(pdffilename, password);
if(new File(imgFileName).exists())
{
tiv.setImageLocation(imgFileName);
updateTexts(1);
progress.dismiss();
}
else
startRenderThread(mPage, mZoom);
}
catch (PDFAuthenticationFailureException e) {
} catch (Exception e) {
}
return true;
}
public synchronized void startRenderThread(final int page, final float zoom) {
if (backgroundThread != null)
return;
backgroundThread = new Thread(new Runnable() {
public void run() {
try {
if (mPdfFile != null) {
generatePDFPage(page, zoom);
}
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
backgroundThread = null;
}
});
backgroundThread.start();
}
public void nextPage() {
if (mPdfFile != null) {
if (mPage < mPdfFile.getNumPages()) {
mPage += 1;
imgFileName= pdffilename.substring(0, pdffilename.lastIndexOf("."))+"_"+String.valueOf(mPage)+".jpg";
if(new File(imgFileName).exists())
{
tiv.setImageLocation(imgFileName);
updateTexts(mPage);
progress.dismiss();
}
else
{
progress = ProgressDialog.show(activity, "Loading", "Loading PDF Page " + mPage, true, true);
startRenderThread(mPage, STARTZOOM);
}
}
}
}
public void prevPage() {
if (mPdfFile != null) {
if (mPage > 1) {
mPage -= 1;
imgFileName= pdffilename.substring(0, pdffilename.lastIndexOf("."))+"_"+String.valueOf(mPage)+".jpg";
if(new File(imgFileName).exists())
{
tiv.setImageLocation(imgFileName);
updateTexts(mPage);
progress.dismiss();
}
else
{
progress = ProgressDialog.show(activity, "Loading", "Loading PDF Page " + mPage, true, true);
startRenderThread(mPage, STARTZOOM);
}
}
}
}
protected void updateTexts(int pageNo) {
if (mPdfFile != null) {
tv_page_no.setText("Page "+pageNo+"/"+mPdfFile.getNumPages());
if(mPdfFile.getNumPages() > 1)
{
if(pageNo==1)
leftArrow.setVisibility(View.GONE);
else
leftArrow.setVisibility(View.VISIBLE);
if(pageNo == mPdfFile.getNumPages())
rightArrow.setVisibility(View.GONE);
else
rightArrow.setVisibility(View.VISIBLE);
}
}
}
public void generatePDFPage(final int page, float zoom) throws Exception {
try {
// Only load the page if it's a different page (i.e. not just changing the zoom level)
if (mPdfPage == null || mPdfPage.getPageNumber() != page) {
mPdfPage = mPdfFile.getPage(page, true);
}
float width = mPdfPage.getWidth();
float height = mPdfPage.getHeight();
RectF clip = null;
Bitmap bmp = mPdfPage.getImage((int)(width*zoom), (int)(height*zoom), clip, true, true);
//imgFileName += String.valueOf(page)+".jpg";
FileOutputStream fo = null;
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 50, bytes);
File f = new File(imgFileName);
f.createNewFile();
fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (Exception ex) {
} finally {
if (fo != null) {
try {
fo.close();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
activity.runOnUiThread(new Runnable() {
public void run() {
tiv.setImageLocation(imgFileName);
//tiv.setImageBitmap(BitmapFactory.decodeFile(imgFileName));
updateTexts(page);
if (progress != null)
progress.dismiss();
}
});
} catch (Throwable e) {
Log.e(TAG, e.getMessage(), e);
}
}
public void parsePDF(String filename, String password) throws PDFAuthenticationFailureException {
pdffilename = filename;
try {
File f = new File(filename);
long len = f.length();
if (len == 0) {
}
else {
openFile(f, password);
}
}
catch (PDFAuthenticationFailureException e) {
throw e;
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* <p>Open a specific pdf file. Creates a DocumentInfo from the file,
* and opens that.</p>
*
* <p><b>Note:</b> Mapping the file locks the file until the PDFFile
* is closed.</p>
*
* #param file the file to open
* #throws IOException
*/
public void openFile(File file, String password) throws IOException {
// first open the file for random access
RandomAccessFile raf = null;
try
{
raf = new RandomAccessFile(file, "r");
// extract a file channel
FileChannel channel = raf.getChannel();
// now memory-map a byte-buffer
ByteBuffer bb = ByteBuffer.NEW(channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()));
// create a PDFFile from the data
if (password == null)
mPdfFile = new PDFFile(bb);
else
mPdfFile = new PDFFile(bb, new PDFPassword(password));
} catch (Exception ex)
{
} finally {
raf.close();
}
}
}
This is load PDF in fragment use PDFViewer
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_keluarga, container, false);
pdfView = (PDFView) v.findViewById(R.id.keluargaPdf);
pdfView.fromAsset("tiga.pdf").load();
// Inflate the layout for this fragment
return v;
}