Example usage for android.view.animation TranslateAnimation setAnimationListener

List of usage examples for android.view.animation TranslateAnimation setAnimationListener

Introduction

In this page you can find the example usage for android.view.animation TranslateAnimation setAnimationListener.

Prototype

public void setAnimationListener(AnimationListener listener) 

Source Link

Document

Binds an animation listener to this animation.

Usage

From source file:com.linkbubble.ui.BubbleFlowView.java

protected void remove(final int index, boolean animateOff, boolean removeFromList,
        final OnRemovedListener onRemovedListener) {
    if (index < 0 || index >= mViews.size()) {
        return;// ww w.  j  av a2 s.co  m
    }
    final View view = mViews.get(index);

    if (animateOff) {
        if (removeFromList == false) {
            throw new RuntimeException("removeFromList must be true if animating off");
        }
        TranslateAnimation slideOffAnim = new TranslateAnimation(0, 0, 0, -mItemHeight);
        slideOffAnim.setDuration(Constant.BUBBLE_FLOW_ANIM_TIME);
        slideOffAnim.setFillAfter(true);
        slideOffAnim.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                mContent.removeView(view);

                // Cancel the current animation on the views so the offset no longer applies
                for (int i = 0; i < mViews.size(); i++) {
                    View view = mViews.get(i);
                    Animation viewAnimation = view.getAnimation();
                    if (viewAnimation != null) {
                        viewAnimation.cancel();
                        view.setAnimation(null);
                    }
                }
                updatePositions();
                updateScales(getScrollX());
                mSlideOffAnimationPlaying = false;

                if (onRemovedListener != null) {
                    onRemovedListener.onRemoved(view);
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        invalidate(); // This fixes #284 - it's a hack, but it will do for now.
        view.startAnimation(slideOffAnim);
        mSlideOffAnimationPlaying = true;

        mViews.remove(view);

        int viewsSize = mViews.size();
        if (index < viewsSize) {
            for (int i = index; i < viewsSize; i++) {
                final View viewToShift = mViews.get(i);
                TranslateAnimationEx slideAnim = new TranslateAnimationEx(0, -mItemWidth, 0, 0,
                        new TranslateAnimationEx.TransformationListener() {
                            @Override
                            public void onApplyTransform(float interpolatedTime, Transformation t, float dx,
                                    float dy) {
                                float centerX = getScrollX() + (mWidth / 2) - (mItemWidth / 2);
                                updateScaleForView(viewToShift, centerX, viewToShift.getX() + dx);
                            }
                        });
                slideAnim.setDuration(Constant.BUBBLE_FLOW_ANIM_TIME);
                slideAnim.setFillAfter(true);
                viewToShift.startAnimation(slideAnim);
            }
        } else if (viewsSize > 0) {
            for (int i = 0; i < index; i++) {
                final View viewToShift = mViews.get(i);
                TranslateAnimationEx slideAnim = new TranslateAnimationEx(0, mItemWidth, 0, 0,
                        new TranslateAnimationEx.TransformationListener() {
                            @Override
                            public void onApplyTransform(float interpolatedTime, Transformation t, float dx,
                                    float dy) {
                                float centerX = getScrollX() + (mWidth / 2) - (mItemWidth / 2);
                                updateScaleForView(viewToShift, centerX, viewToShift.getX() + dx);
                            }
                        });
                slideAnim.setDuration(Constant.BUBBLE_FLOW_ANIM_TIME);
                slideAnim.setFillAfter(true);
                viewToShift.startAnimation(slideAnim);
            }
        }
    } else {
        mContent.removeView(view);
        if (removeFromList) {
            mViews.remove(view);
            updatePositions();
            updateScales(getScrollX());
            mContent.invalidate();
        }
        if (onRemovedListener != null) {
            onRemovedListener.onRemoved(view);
        }
    }
}

From source file:org.mozilla.gecko.home.BrowserSearch.java

private void setSuggestionsEnabled(final boolean enabled) {
    // Clicking the yes/no buttons quickly can cause the click events be
    // queued before the listeners are removed above, so it's possible
    // setSuggestionsEnabled() can be called twice. mSuggestionsOptInPrompt
    // can be null if this happens (bug 828480).
    if (mSuggestionsOptInPrompt == null) {
        return;/*  w  w  w . ja  va2 s . c o  m*/
    }

    // Make suggestions appear immediately after the user opts in
    ThreadUtils.postToBackgroundThread(new Runnable() {
        @Override
        public void run() {
            SuggestClient client = mSuggestClient;
            if (client != null) {
                client.query(mSearchTerm);
            }
        }
    });

    // Pref observer in gecko will also set prompted = true
    PrefsHelper.setPref("browser.search.suggest.enabled", enabled);

    TranslateAnimation slideAnimation = new TranslateAnimation(0, mSuggestionsOptInPrompt.getWidth(), 0, 0);
    slideAnimation.setDuration(ANIMATION_DURATION);
    slideAnimation.setInterpolator(new AccelerateInterpolator());
    slideAnimation.setFillAfter(true);
    final View prompt = mSuggestionsOptInPrompt.findViewById(R.id.prompt);

    TranslateAnimation shrinkAnimation = new TranslateAnimation(0, 0, 0,
            -1 * mSuggestionsOptInPrompt.getHeight());
    shrinkAnimation.setDuration(ANIMATION_DURATION);
    shrinkAnimation.setFillAfter(true);
    shrinkAnimation.setStartOffset(slideAnimation.getDuration());
    shrinkAnimation.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation a) {
            // Increase the height of the view so a gap isn't shown during animation
            mView.getLayoutParams().height = mView.getHeight() + mSuggestionsOptInPrompt.getHeight();
            mView.requestLayout();
        }

        @Override
        public void onAnimationRepeat(Animation a) {
        }

        @Override
        public void onAnimationEnd(Animation a) {
            // Removing the view immediately results in a NPE in
            // dispatchDraw(), possibly because this callback executes
            // before drawing is finished. Posting this as a Runnable fixes
            // the issue.
            mView.post(new Runnable() {
                @Override
                public void run() {
                    mView.removeView(mSuggestionsOptInPrompt);
                    mList.clearAnimation();
                    mSuggestionsOptInPrompt = null;

                    if (enabled) {
                        // Reset the view height
                        mView.getLayoutParams().height = LayoutParams.MATCH_PARENT;

                        mSuggestionsEnabled = enabled;
                        mAnimateSuggestions = true;
                        mAdapter.notifyDataSetChanged();
                        filterSuggestions();
                    }
                }
            });
        }
    });

    prompt.startAnimation(slideAnimation);
    mSuggestionsOptInPrompt.startAnimation(shrinkAnimation);
    mList.startAnimation(shrinkAnimation);
}

From source file:com.smp.musicspeed.MainActivity.java

private void animateLinkOn() {

    TranslateAnimation anim = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
            Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
            -1.0f);/*from   ww  w. j  a v  a2 s  .c o  m*/
    anim.setDuration(TRANS_ANIMATION_TIME);
    anim.setInterpolator(new AnticipateOvershootInterpolator());
    anim.setAnimationListener(new AnimationListenerAdaptor() {
        @Override
        public void onAnimationEnd(Animation animation) {
            rateText.setAlpha(0f);
            linkOn();

            rateText.animate().alpha(1f).setDuration(TRANS_ANIMATION_TIME)
                    .setListener(new AnimatorListenerAdapter() {
                    });
        }
    });
    tempoCard.startAnimation(anim);
    tempoText.animate().alpha(0f).setDuration(TEXT_ANIMATION_TIME).setListener(new AnimatorListenerAdapter() {
    });
}

From source file:com.smp.musicspeed.MainActivity.java

private void animateLinkOff() {
    linkOff();/*from   w  w w  . j  a v  a  2 s .  c o  m*/
    tempoCard.setVisibility(View.INVISIBLE);

    TranslateAnimation anim = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
            Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
            1.0f);
    anim.setDuration(TRANS_ANIMATION_TIME);
    anim.setInterpolator(new AnticipateOvershootInterpolator());
    anim.setAnimationListener(new AnimationListenerAdaptor() {
        @Override
        public void onAnimationEnd(Animation animation) {
            tempoText.setAlpha(0f);
            linkOff();

            tempoText.animate().alpha(1f).setDuration(TEXT_ANIMATION_TIME)
                    .setListener(new AnimatorListenerAdapter() {
                    });
        }
    });
    rateCard.startAnimation(anim);
    rateText.animate().alpha(0f).setDuration(TRANS_ANIMATION_TIME).setListener(new AnimatorListenerAdapter() {
    });
}

From source file:com.adityarathi.muo.ui.activities.NowPlayingActivity.java

/**
 * Slides in the controls bar from the bottom along with a
 * slight rotation.//www  .  j av  a2s.  c o m
 */
private void animateInControlsBar() {
    android.view.animation.TranslateAnimation slideUp = new android.view.animation.TranslateAnimation(
            Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
            2.0f, Animation.RELATIVE_TO_SELF, 0.0f);
    slideUp.setDuration(300);
    slideUp.setInterpolator(new DecelerateInterpolator(2.0f));

    slideUp.setAnimationListener(new Animation.AnimationListener() {

        @Override
        public void onAnimationStart(Animation animation) {
            mControlsLayoutHeaderParent.setVisibility(View.VISIBLE);
        }

        @Override
        public void onAnimationEnd(Animation animation) {

        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }

    });

    mControlsLayoutHeaderParent.startAnimation(slideUp);
}

From source file:com.juick.android.MessagesFragment.java

public void scrollToX(int scrollX, long duration) {
    currentScrollX = scrollX;/*w  w  w. jav a  2 s  . c o  m*/
    final View frag = getActivity().findViewById(R.id.messagesfragment);
    TranslateAnimation ta = new TranslateAnimation(lastToXDelta != null ? lastToXDelta : 0, -scrollX, 0, 0);
    lastToXDelta = -scrollX;
    ta.setFillEnabled(true);
    ta.setDuration(duration);
    ta.setFillAfter(true);
    ta.setFillBefore(true);
    if (parent instanceof MainActivity) {
        final View navPanel = parent.findViewById(R.id.navigation_panel);
        navPanel.setVisibility(View.VISIBLE);
    }
    if (duration > 2) {
        ta.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                if (mScrollState == SCROLL_STATE_SETTLING) {
                    setScrollState(SCROLL_STATE_IDLE);
                    frag.clearAnimation();
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                //To change body of implemented methods use File | Settings | File Templates.
            }
        });
    }
    frag.startAnimation(ta);
}

From source file:com.rareventure.gps2.reviewer.map.OsmMapGpsTrailerReviewerMapActivity.java

private void slideSas(final SasPanelState newState) {
    final TranslateAnimation anim;

    if (newState == SasPanelState.FULL) {
        if (sasPanelState == SasPanelState.GONE)
            anim = slideSasNoneToFull;// w ww.j av  a2s  .c  o m
        else if (sasPanelState == SasPanelState.TAB) {
            anim = slideSasTabToFull;
        } else
            return; //nothing to do
    } else if (newState == SasPanelState.TAB) {
        if (sasPanelState == SasPanelState.GONE)
            anim = slideSasNoneToTab;
        //            throw new IllegalStateException("not supported");
        else if (sasPanelState == SasPanelState.FULL)
            anim = slideSasFullToTab;
        else
            return; //nothing to do
    } else //if(newState == SasPanelState.GONE)
    {
        if (sasPanelState == SasPanelState.TAB)
            anim = slideSasTabToNone;
        else if (sasPanelState == SasPanelState.FULL)
            anim = slideSasFullToNone;
        else
            return; //nothing to do
    }

    if (sasPanelState == SasPanelState.TAB)
        sasPanel.findViewById(R.id.sas_main_panel).setVisibility(View.VISIBLE);
    sasPanel.startAnimation(anim);
    anim.setAnimationListener(new AnimationListener() {

        @Override
        public void onAnimationStart(Animation animation) {
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }

        @Override
        public void onAnimationEnd(Animation animation) {
            if (newState == SasPanelState.TAB) {
                sasPanel.findViewById(R.id.sas_main_panel).setVisibility(View.GONE);
                sasPanelButton.setBackgroundResource(R.drawable.sas_tab_out);
            } else
                sasPanelButton.setBackgroundResource(R.drawable.sas_tab_in);

            sasPanel.setVisibility(newState != SasPanelState.GONE ? View.VISIBLE : View.INVISIBLE);

            sasPanelState = newState;
        }
    });

}

From source file:it.unipr.ce.dsg.gamidroid.activities.NAM4JAndroidActivity.java

/**
 * Method to display the menu of the app.
 */// www .j  a v a  2 s. c o  m
private void displaySideMenu() {

    TranslateAnimation animation = null;

    // If it's a tablet in landscape, the menu is always displayed, else
    // it's activated by the user
    if (!isTablet || (isTablet && screenOrientation == Orientation.PORTRAIT)) {
        if (!showingMenu) {

            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mainRL.getLayoutParams();

            animation = new TranslateAnimation(0, listRL.getMeasuredWidth() - layoutParams.leftMargin, 0, 0);

            animation.setDuration(animationDuration);
            animation.setFillEnabled(true);
            animation.setAnimationListener(new AnimationListener() {

                @Override
                public void onAnimationStart(Animation animation) {
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }

                @Override
                public void onAnimationEnd(Animation animation) {

                    // At the end, set the final position as the current one
                    RelativeLayout.LayoutParams lpList = (LayoutParams) mainRL.getLayoutParams();
                    lpList.setMargins(listRL.getMeasuredWidth(), 0, -listRL.getMeasuredWidth(), 0);
                    mainRL.setLayoutParams(lpList);

                    showingMenu = true;
                }
            });

        } else {

            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mainRL.getLayoutParams();

            animation = new TranslateAnimation(0, -layoutParams.leftMargin, 0, 0);
            animation.setDuration(animationDuration);
            animation.setFillEnabled(true);
            animation.setAnimationListener(new AnimationListener() {

                @Override
                public void onAnimationStart(Animation animation) {
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }

                @Override
                public void onAnimationEnd(Animation animation) {

                    // At the end, set the final position as the current one
                    RelativeLayout.LayoutParams mainContenrLP = (LayoutParams) mainRL.getLayoutParams();
                    mainContenrLP.setMargins(0, 0, 0, 0);
                    mainRL.setLayoutParams(mainContenrLP);

                    showingMenu = false;
                }
            });
        }

        mainRL.startAnimation(animation);
    }

    else {
        // Showing the menu since the tablet is in landscape orientation
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mainRL.getLayoutParams();

        animation = new TranslateAnimation(0, listRL.getMeasuredWidth() - layoutParams.leftMargin, 0, 0);

        animation.setDuration(animationDuration);
        animation.setFillEnabled(true);
        animation.setAnimationListener(new AnimationListener() {

            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {

                // At the end, set the final position as the current one
                RelativeLayout.LayoutParams lpList = (LayoutParams) mainRL.getLayoutParams();
                lpList.setMargins(listRL.getMeasuredWidth(), 0, -listRL.getMeasuredWidth(), 0);
                mainRL.setLayoutParams(lpList);

                showingMenu = true;
            }
        });

        mainRL.startAnimation(animation);
    }
}

From source file:de.tum.in.tumcampus.auxiliary.calendar.DayView.java

private View switchViews(boolean forward, float xOffSet, float width, float velocity) {
    mAnimationDistance = width - xOffSet;

    float progress = Math.abs(xOffSet) / width;
    if (progress > 1.0f) {
        progress = 1.0f;/* w  w w.jav  a  2s  .c o m*/
    }

    float inFromXValue, inToXValue;
    float outFromXValue, outToXValue;
    if (forward) {
        inFromXValue = 1.0f - progress;
        inToXValue = 0.0f;
        outFromXValue = -progress;
        outToXValue = -1.0f;
    } else {
        inFromXValue = progress - 1.0f;
        inToXValue = 0.0f;
        outFromXValue = progress;
        outToXValue = 1.0f;
    }

    final Time start = new Time(mBaseDate.timezone);
    start.set(mController.getTime());
    if (forward) {
        start.monthDay += mNumDays;
    } else {
        start.monthDay -= mNumDays;
    }
    mController.setTime(start.normalize(true));

    Time newSelected = start;

    if (mNumDays == 7) {
        newSelected = new Time(start);
        adjustToBeginningOfWeek(start);
    }

    final Time end = new Time(start);
    end.monthDay += mNumDays - 1;

    // We have to allocate these animation objects each time we switch views
    // because that is the only way to set the animation parameters.
    TranslateAnimation inAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, inFromXValue,
            Animation.RELATIVE_TO_SELF, inToXValue, Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f);

    TranslateAnimation outAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, outFromXValue,
            Animation.RELATIVE_TO_SELF, outToXValue, Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f);

    long duration = calculateDuration(width - Math.abs(xOffSet), width, velocity);
    inAnimation.setDuration(duration);
    inAnimation.setInterpolator(mHScrollInterpolator);
    outAnimation.setInterpolator(mHScrollInterpolator);
    outAnimation.setDuration(duration);
    outAnimation.setAnimationListener(new GotoBroadcaster(start, end));

    mViewSwitcher.setInAnimation(inAnimation);
    mViewSwitcher.setOutAnimation(outAnimation);

    DayView view = (DayView) mViewSwitcher.getCurrentView();
    view.cleanup();
    mViewSwitcher.showNext();
    view = (DayView) mViewSwitcher.getCurrentView();
    view.setSelected(newSelected, true, false);
    view.requestFocus();
    view.reloadEvents();
    view.updateTitle();
    view.restartCurrentTimeUpdates();

    return view;
}

From source file:foam.starwisp.StarwispBuilder.java

public void Update(final StarwispActivity ctx, final String ctxname, JSONArray arr) {

    String type = "";
    Integer tid = 0;/*  ww  w  .  ja  va 2  s .co m*/
    String token = "";

    try {

        type = arr.getString(0);
        tid = arr.getInt(1);
        token = arr.getString(2);

    } catch (JSONException e) {
        Log.e("starwisp",
                "Error parsing update arguments for " + ctxname + " " + arr.toString() + e.toString());
    }

    final Integer id = tid;

    //Log.i("starwisp", "Update: "+type+" "+id+" "+token);

    try {

        // non widget commands
        if (token.equals("toast")) {
            Toast msg = Toast.makeText(ctx.getBaseContext(), arr.getString(3), Toast.LENGTH_SHORT);
            LinearLayout linearLayout = (LinearLayout) msg.getView();
            View child = linearLayout.getChildAt(0);
            TextView messageTextView = (TextView) child;
            messageTextView.setTextSize(arr.getInt(4));
            msg.show();
            return;
        }

        if (token.equals("play-sound")) {
            String name = arr.getString(3);

            if (name.equals("ping")) {
                MediaPlayer mp = MediaPlayer.create(ctx, R.raw.ping);
                mp.start();
            }
            if (name.equals("active")) {
                MediaPlayer mp = MediaPlayer.create(ctx, R.raw.active);
                mp.start();
            }
        }

        if (token.equals("soundfile-start-recording")) {
            String filename = arr.getString(3);
            m_SoundManager.StartRecording(filename);
        }
        if (token.equals("soundfile-stop-recording")) {
            m_SoundManager.StopRecording();
        }
        if (token.equals("soundfile-start-playback")) {
            String filename = arr.getString(3);
            m_SoundManager.StartPlaying(filename);
        }
        if (token.equals("soundfile-stop-playback")) {
            m_SoundManager.StopPlaying();
        }

        if (token.equals("vibrate")) {
            Vibrator v = (Vibrator) ctx.getSystemService(Context.VIBRATOR_SERVICE);
            v.vibrate(arr.getInt(3));
        }

        if (type.equals("replace-fragment")) {
            int ID = arr.getInt(1);
            String name = arr.getString(2);
            Fragment fragment = ActivityManager.GetFragment(name);
            FragmentTransaction ft = ctx.getSupportFragmentManager().beginTransaction();

            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

            //ft.setCustomAnimations(  R.animator.fragment_slide_left_enter,
            //             R.animator.fragment_slide_right_exit);

            //ft.setCustomAnimations(
            //    R.animator.card_flip_right_in, R.animator.card_flip_right_out,
            //    R.animator.card_flip_left_in, R.animator.card_flip_left_out);
            ft.replace(ID, fragment);
            ft.addToBackStack(null);
            ft.commit();
            return;
        }

        if (token.equals("dialog-fragment")) {
            FragmentManager fm = ctx.getSupportFragmentManager();
            final int ID = arr.getInt(3);
            final JSONArray lp = arr.getJSONArray(4);
            final String name = arr.getString(5);

            final Dialog dialog = new Dialog(ctx);
            dialog.setTitle("Title...");

            LinearLayout inner = new LinearLayout(ctx);
            inner.setId(ID);
            inner.setLayoutParams(BuildLayoutParams(lp));

            dialog.setContentView(inner);

            //                Fragment fragment = ActivityManager.GetFragment(name);
            //                FragmentTransaction fragmentTransaction = ctx.getSupportFragmentManager().beginTransaction();
            //                fragmentTransaction.add(ID,fragment);
            //                fragmentTransaction.commit();

            dialog.show();

            /*                DialogFragment df = new DialogFragment() {
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                     Bundle savedInstanceState) {
                LinearLayout inner = new LinearLayout(ctx);
                inner.setId(ID);
                inner.setLayoutParams(BuildLayoutParams(lp));
                    
                return inner;
            }
                    
            @Override
            public Dialog onCreateDialog(Bundle savedInstanceState) {
                Dialog ret = super.onCreateDialog(savedInstanceState);
                Log.i("starwisp","MAKINGDAMNFRAGMENT");
                    
                Fragment fragment = ActivityManager.GetFragment(name);
                FragmentTransaction fragmentTransaction = ctx.getSupportFragmentManager().beginTransaction();
                fragmentTransaction.add(1,fragment);
                fragmentTransaction.commit();
                return ret;
            }
                            };
                            df.show(ctx.getFragmentManager(), "foo");
            */
        }

        if (token.equals("time-picker-dialog")) {

            final Calendar c = Calendar.getInstance();
            int hour = c.get(Calendar.HOUR_OF_DAY);
            int minute = c.get(Calendar.MINUTE);

            // Create a new instance of TimePickerDialog and return it
            TimePickerDialog d = new TimePickerDialog(ctx, null, hour, minute, true);
            d.show();
            return;
        }
        ;

        if (token.equals("view")) {
            //ctx.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse()));

            File f = new File(arr.getString(3));
            Uri fileUri = Uri.fromFile(f);

            Intent myIntent = new Intent(android.content.Intent.ACTION_VIEW);
            String extension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(arr.getString(3));
            String mimetype = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
            myIntent.setDataAndType(fileUri, mimetype);
            ctx.startActivity(myIntent);
            return;
        }

        if (token.equals("make-directory")) {
            File file = new File(((StarwispActivity) ctx).m_AppDir + arr.getString(3));
            file.mkdirs();
            return;
        }

        if (token.equals("list-files")) {
            final String name = arr.getString(3);
            File file = new File(((StarwispActivity) ctx).m_AppDir + arr.getString(5));
            // todo, should probably call callback with empty list
            if (file != null) {
                File list[] = file.listFiles();

                if (list != null) {
                    String code = "(";
                    for (int i = 0; i < list.length; i++) {
                        code += " \"" + list[i].getName() + "\"";
                    }
                    code += ")";

                    DialogCallback(ctx, ctxname, name, code);
                }
            }
            return;
        }

        if (token.equals("gps-start")) {
            final String name = arr.getString(3);

            if (m_LocationManager == null) {
                m_LocationManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
                m_GPS = new DorisLocationListener(m_LocationManager);
            }

            m_GPS.Start((StarwispActivity) ctx, name, this, arr.getInt(5), arr.getInt(6));
            return;
        }

        if (token.equals("sensors-get")) {
            final String name = arr.getString(3);
            if (m_SensorHandler == null) {
                m_SensorHandler = new SensorHandler((StarwispActivity) ctx, this);
            }
            m_SensorHandler.GetSensors((StarwispActivity) ctx, name, this);
            return;
        }

        if (token.equals("sensors-start")) {
            final String name = arr.getString(3);
            final JSONArray requested_json = arr.getJSONArray(5);
            ArrayList<Integer> requested = new ArrayList<Integer>();

            try {
                for (int i = 0; i < requested_json.length(); i++) {
                    requested.add(requested_json.getInt(i));
                }
            } catch (JSONException e) {
                Log.e("starwisp", "Error parsing data in sensors start " + e.toString());
            }

            // start it up...
            if (m_SensorHandler == null) {
                m_SensorHandler = new SensorHandler((StarwispActivity) ctx, this);
            }
            m_SensorHandler.StartSensors((StarwispActivity) ctx, name, this, requested);
            return;
        }

        if (token.equals("sensors-stop")) {
            if (m_SensorHandler != null) {
                m_SensorHandler.StopSensors();
            }
            return;
        }

        if (token.equals("walk-draggable")) {
            final String name = arr.getString(3);
            int iid = arr.getInt(5);
            DialogCallback(ctx, ctxname, name, WalkDraggable(ctx, name, ctxname, iid).replace("\\", ""));
            return;
        }

        if (token.equals("delayed")) {
            final String name = arr.getString(3);
            final int d = arr.getInt(5);
            Runnable timerThread = new Runnable() {
                public void run() {
                    DialogCallback(ctx, ctxname, name, "");
                }
            };
            m_Handler.removeCallbacksAndMessages(null);
            m_Handler.postDelayed(timerThread, d);
            return;
        }

        if (token.equals("network-connect")) {
            final String name = arr.getString(3);
            final String ssid = arr.getString(5);
            m_NetworkManager.Start(ssid, (StarwispActivity) ctx, name, this);
            return;
        }

        if (token.equals("http-request")) {
            Log.i("starwisp", "http-request called");
            if (m_NetworkManager.state == NetworkManager.State.CONNECTED) {
                Log.i("starwisp", "attempting http request");
                final String name = arr.getString(3);
                final String url = arr.getString(5);
                m_NetworkManager.StartRequestThread(url, "normal", "", name);
            }
            return;
        }

        if (token.equals("http-post")) {
            Log.i("starwisp", "http-post called");
            if (m_NetworkManager.state == NetworkManager.State.CONNECTED) {
                Log.i("starwisp", "attempting http request");
                final String name = arr.getString(3);
                final String url = arr.getString(5);
                final String data = arr.getString(6);
                m_NetworkManager.StartRequestThread(url, "post", data, name);
            }
            return;
        }

        if (token.equals("http-upload")) {
            if (m_NetworkManager.state == NetworkManager.State.CONNECTED) {
                Log.i("starwisp", "attempting http ul request");
                final String filename = arr.getString(4);
                final String url = arr.getString(5);
                m_NetworkManager.StartRequestThread(url, "upload", "", filename);
            }
            return;
        }

        if (token.equals("http-download")) {
            if (m_NetworkManager.state == NetworkManager.State.CONNECTED) {
                Log.i("starwisp", "attempting http dl request");
                final String filename = arr.getString(4);
                final String url = arr.getString(5);
                m_NetworkManager.StartRequestThread(url, "download", "", filename);
            }
            return;
        }

        if (token.equals("take-photo")) {
            photo(ctx, arr.getString(3), arr.getInt(4));
        }

        if (token.equals("bluetooth")) {
            final String name = arr.getString(3);
            m_Bluetooth.Start((StarwispActivity) ctx, name, this);
            return;
        }

        if (token.equals("bluetooth-send")) {
            m_Bluetooth.Write(arr.getString(3));
        }

        if (token.equals("process-image-in-place")) {
            BitmapCache.ProcessInPlace(arr.getString(3));
        }

        if (token.equals("send-mail")) {
            final String to[] = new String[1];
            to[0] = arr.getString(3);
            final String subject = arr.getString(4);
            final String body = arr.getString(5);

            JSONArray attach = arr.getJSONArray(6);
            ArrayList<String> paths = new ArrayList<String>();
            for (int a = 0; a < attach.length(); a++) {
                Log.i("starwisp", attach.getString(a));
                paths.add(attach.getString(a));
            }

            email(ctx, to[0], "", subject, body, paths);
        }

        if (token.equals("date-picker-dialog")) {
            final Calendar c = Calendar.getInstance();
            int day = c.get(Calendar.DAY_OF_MONTH);
            int month = c.get(Calendar.MONTH);
            int year = c.get(Calendar.YEAR);

            final String name = arr.getString(3);

            // Create a new instance of TimePickerDialog and return it
            DatePickerDialog d = new DatePickerDialog(ctx, new DatePickerDialog.OnDateSetListener() {
                public void onDateSet(DatePicker view, int year, int month, int day) {
                    DialogCallback(ctx, ctxname, name, day + " " + month + " " + year);
                }
            }, year, month, day);
            d.show();
            return;
        }
        ;

        if (token.equals("alert-dialog")) {
            final String name = arr.getString(3);
            final String msg = arr.getString(5);
            DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    int result = 0;
                    if (which == DialogInterface.BUTTON_POSITIVE)
                        result = 1;
                    DialogCallback(ctx, ctxname, name, "" + result);
                }
            };
            AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
            builder.setMessage(msg).setPositiveButton("Yes", dialogClickListener)
                    .setNegativeButton("No", dialogClickListener).show();
            return;
        }

        if (token.equals("ok-dialog")) {
            final String name = arr.getString(3);
            final String msg = arr.getString(5);
            DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    int result = 0;
                    if (which == DialogInterface.BUTTON_POSITIVE)
                        result = 1;
                    DialogCallback(ctx, ctxname, name, "" + result);
                }
            };
            AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
            builder.setMessage(msg).setPositiveButton("Ok", dialogClickListener).show();
            return;
        }

        if (token.equals("start-activity")) {
            ActivityManager.StartActivity(ctx, arr.getString(3), arr.getInt(4), arr.getString(5));
            return;
        }

        if (token.equals("start-activity-goto")) {
            ActivityManager.StartActivityGoto(ctx, arr.getString(3), arr.getString(4));
            return;
        }

        if (token.equals("finish-activity")) {
            ctx.setResult(arr.getInt(3));
            ctx.finish();
            return;
        }

        ///////////////////////////////////////////////////////////

        if (id == 0) {
            Log.i("starwisp", "Zero ID, aborting...");
            return;
        }

        // now try and find the widget
        final View vv = ctx.findViewById(id);
        if (vv == null) {
            Log.i("starwisp", "Can't find widget : " + id);
            return;
        }

        // tokens that work on everything
        if (token.equals("hide")) {
            vv.setVisibility(View.GONE);
            return;
        }

        if (token.equals("show")) {
            vv.setVisibility(View.VISIBLE);
            return;
        }

        // only tested on spinners
        if (token.equals("disabled")) {
            vv.setAlpha(0.3f);
            //vv.getSelectedView().setEnabled(false);
            vv.setEnabled(false);
            return;
        }

        if (token.equals("enabled")) {
            vv.setAlpha(1.0f);
            //vv.getSelectedView().setEnabled(true);
            vv.setEnabled(true);
            return;
        }

        if (token.equals("animate")) {
            JSONArray trans = arr.getJSONArray(3);

            final TranslateAnimation animation = new TranslateAnimation(getPixelsFromDp(ctx, trans.getInt(0)),
                    getPixelsFromDp(ctx, trans.getInt(1)), getPixelsFromDp(ctx, trans.getInt(2)),
                    getPixelsFromDp(ctx, trans.getInt(3)));
            animation.setDuration(1000);
            animation.setFillAfter(false);
            animation.setInterpolator(new AnticipateOvershootInterpolator(1.0f));
            animation.setAnimationListener(new AnimationListener() {
                @Override
                public void onAnimationEnd(Animation animation) {
                    vv.clearAnimation();
                    Log.i("starwisp", "animation end");
                    ((ViewManager) vv.getParent()).removeView(vv);

                    //LayoutParams lp = new LayoutParams(imageView.getWidth(), imageView.getHeight());
                    //lp.setMargins(50, 100, 0, 0);
                    //imageView.setLayoutParams(lp);
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }

                @Override
                public void onAnimationStart(Animation animation) {
                    Log.i("starwisp", "animation start");
                }

            });

            vv.startAnimation(animation);
            return;
        }

        // tokens that work on everything
        if (token.equals("set-enabled")) {
            Log.i("starwisp", "set-enabled called...");
            vv.setEnabled(arr.getInt(3) == 1);
            vv.setClickable(arr.getInt(3) == 1);
            if (vv.getBackground() != null) {
                if (arr.getInt(3) == 0) {
                    //vv.setBackgroundColor(0x00000000);
                    vv.getBackground().setColorFilter(0x20000000, PorterDuff.Mode.MULTIPLY);
                } else {
                    vv.getBackground().setColorFilter(null);
                }
            }
            return;
        }

        if (token.equals("background-colour")) {
            JSONArray col = arr.getJSONArray(3);

            if (type.equals("linear-layout")) {
                vv.setBackgroundColor(Color.argb(col.getInt(3), col.getInt(0), col.getInt(1), col.getInt(2)));
            } else {
                //vv.setBackgroundColor();
                vv.getBackground().setColorFilter(
                        Color.argb(col.getInt(3), col.getInt(0), col.getInt(1), col.getInt(2)),
                        PorterDuff.Mode.MULTIPLY);
            }
            vv.invalidate();
            return;
        }

        // special cases

        if (type.equals("linear-layout")) {
            //Log.i("starwisp","linear-layout update id: "+id);
            StarwispLinearLayout.Update(this, (LinearLayout) vv, token, ctx, ctxname, arr);
            return;
        }

        if (type.equals("relative-layout")) {
            StarwispRelativeLayout.Update(this, (RelativeLayout) vv, token, ctx, ctxname, arr);
            return;
        }

        if (type.equals("draggable")) {
            LinearLayout v = (LinearLayout) vv;
            if (token.equals("contents")) {
                v.removeAllViews();
                JSONArray children = arr.getJSONArray(3);
                for (int i = 0; i < children.length(); i++) {
                    Build(ctx, ctxname, new JSONArray(children.getString(i)), v);
                }
            }

            if (token.equals("contents-add")) {
                JSONArray children = arr.getJSONArray(3);
                for (int i = 0; i < children.length(); i++) {
                    Build(ctx, ctxname, new JSONArray(children.getString(i)), v);
                }
            }
        }

        if (type.equals("button-grid")) {
            LinearLayout horiz = (LinearLayout) vv;

            if (token.equals("grid-buttons")) {
                horiz.removeAllViews();

                JSONArray params = arr.getJSONArray(3);
                String buttontype = params.getString(0);
                int height = params.getInt(1);
                int textsize = params.getInt(2);
                LayoutParams lp = BuildLayoutParams(params.getJSONArray(3));
                final JSONArray buttons = params.getJSONArray(4);
                final int count = buttons.length();
                int vertcount = 0;
                LinearLayout vert = null;

                for (int i = 0; i < count; i++) {
                    JSONArray button = buttons.getJSONArray(i);

                    if (vertcount == 0) {
                        vert = new LinearLayout(ctx);
                        vert.setId(0);
                        vert.setOrientation(LinearLayout.VERTICAL);
                        horiz.addView(vert);
                    }
                    vertcount = (vertcount + 1) % height;

                    if (buttontype.equals("button")) {
                        Button b = new Button(ctx);
                        b.setId(button.getInt(0));
                        b.setText(button.getString(1));
                        b.setTextSize(textsize);
                        b.setLayoutParams(lp);
                        b.setTypeface(((StarwispActivity) ctx).m_Typeface);
                        final String fn = params.getString(5);
                        b.setOnClickListener(new View.OnClickListener() {
                            public void onClick(View v) {
                                CallbackArgs(ctx, ctxname, id, "" + v.getId() + " #t");
                            }
                        });
                        vert.addView(b);
                    } else if (buttontype.equals("toggle")) {
                        ToggleButton b = new ToggleButton(ctx);
                        b.setId(button.getInt(0));
                        b.setText(button.getString(1));
                        b.setTextSize(textsize);
                        b.setLayoutParams(lp);
                        b.setTypeface(((StarwispActivity) ctx).m_Typeface);
                        final String fn = params.getString(5);
                        b.setOnClickListener(new View.OnClickListener() {
                            public void onClick(View v) {
                                String arg = "#f";
                                if (((ToggleButton) v).isChecked())
                                    arg = "#t";
                                CallbackArgs(ctx, ctxname, id, "" + v.getId() + " " + arg);
                            }
                        });
                        vert.addView(b);
                    } else if (buttontype.equals("single")) {
                        ToggleButton b = new ToggleButton(ctx);
                        b.setId(button.getInt(0));
                        b.setText(button.getString(1));
                        b.setTextSize(textsize);
                        b.setLayoutParams(lp);
                        b.setTypeface(((StarwispActivity) ctx).m_Typeface);
                        final String fn = params.getString(5);
                        b.setOnClickListener(new View.OnClickListener() {
                            public void onClick(View v) {
                                try {
                                    for (int i = 0; i < count; i++) {
                                        JSONArray button = buttons.getJSONArray(i);
                                        int bid = button.getInt(0);
                                        if (bid != v.getId()) {
                                            ToggleButton tb = (ToggleButton) ctx.findViewById(bid);
                                            tb.setChecked(false);
                                        }
                                    }
                                } catch (JSONException e) {
                                    Log.e("starwisp", "Error parsing on click data " + e.toString());
                                }

                                CallbackArgs(ctx, ctxname, id, "" + v.getId() + " #t");
                            }
                        });
                        vert.addView(b);
                    }

                }
            }
        }

        /*
                    if (type.equals("grid-layout")) {
        GridLayout v = (GridLayout)vv;
        if (token.equals("contents")) {
            v.removeAllViews();
            JSONArray children = arr.getJSONArray(3);
            for (int i=0; i<children.length(); i++) {
                Build(ctx,ctxname,new JSONArray(children.getString(i)), v);
            }
        }
                    }
        */
        if (type.equals("view-pager")) {
            ViewPager v = (ViewPager) vv;
            if (token.equals("switch")) {
                v.setCurrentItem(arr.getInt(3));
            }
            if (token.equals("pages")) {
                final JSONArray items = arr.getJSONArray(3);
                v.setAdapter(new FragmentPagerAdapter(ctx.getSupportFragmentManager()) {
                    @Override
                    public int getCount() {
                        return items.length();
                    }

                    @Override
                    public Fragment getItem(int position) {
                        try {
                            String fragname = items.getString(position);
                            return ActivityManager.GetFragment(fragname);
                        } catch (JSONException e) {
                            Log.e("starwisp", "Error parsing pages data " + e.toString());
                        }
                        return null;
                    }
                });
            }
        }

        if (type.equals("image-view")) {
            ImageView v = (ImageView) vv;
            if (token.equals("image")) {
                int iid = ctx.getResources().getIdentifier(arr.getString(3), "drawable", ctx.getPackageName());
                v.setImageResource(iid);
            }
            if (token.equals("external-image")) {
                v.setImageBitmap(BitmapCache.Load(arr.getString(3)));
            }
            return;
        }

        if (type.equals("text-view") || type.equals("debug-text-view")) {
            TextView v = (TextView) vv;
            if (token.equals("text")) {
                if (type.equals("debug-text-view")) {
                    //v.setMovementMethod(new ScrollingMovementMethod());
                }
                v.setText(Html.fromHtml(arr.getString(3)), BufferType.SPANNABLE);
                //                    v.invalidate();
            }
            if (token.equals("file")) {
                v.setText(LoadData(arr.getString(3)));
            }

            return;
        }

        if (type.equals("edit-text")) {
            EditText v = (EditText) vv;
            if (token.equals("text")) {
                v.setText(arr.getString(3));
            }
            if (token.equals("request-focus")) {
                v.requestFocus();
                InputMethodManager imm = (InputMethodManager) ctx
                        .getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT);
            }
            return;
        }

        if (type.equals("button")) {
            Button v = (Button) vv;
            if (token.equals("text")) {
                v.setText(arr.getString(3));
            }

            if (token.equals("listener")) {
                final String fn = arr.getString(3);
                v.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                        m_Scheme.eval("(" + fn + ")");
                    }
                });
            }
            return;
        }

        if (type.equals("toggle-button")) {
            ToggleButton v = (ToggleButton) vv;
            if (token.equals("text")) {
                v.setText(arr.getString(3));
                return;
            }

            if (token.equals("checked")) {
                if (arr.getInt(3) == 0)
                    v.setChecked(false);
                else
                    v.setChecked(true);
                return;
            }

            if (token.equals("listener")) {
                final String fn = arr.getString(3);
                v.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                        m_Scheme.eval("(" + fn + ")");
                    }
                });
            }
            return;
        }

        if (type.equals("canvas")) {
            StarwispCanvas v = (StarwispCanvas) vv;
            if (token.equals("drawlist")) {
                v.SetDrawList(arr.getJSONArray(3));
            }
            return;
        }

        if (type.equals("camera-preview")) {
            final CameraPreview v = (CameraPreview) vv;

            if (token.equals("take-picture")) {
                final String path = ((StarwispActivity) ctx).m_AppDir + arr.getString(3);

                v.TakePicture(new PictureCallback() {
                    public void onPictureTaken(byte[] input, Camera camera) {
                        Bitmap original = BitmapFactory.decodeByteArray(input, 0, input.length);
                        Bitmap resized = Bitmap.createScaledBitmap(original, PHOTO_WIDTH, PHOTO_HEIGHT, true);
                        ByteArrayOutputStream blob = new ByteArrayOutputStream();
                        resized.compress(Bitmap.CompressFormat.JPEG, 100, blob);

                        String datetime = getDateTime();
                        String filename = path + datetime + ".jpg";
                        SaveData(filename, blob.toByteArray());
                        v.Shutdown();
                        ctx.finish();
                    }
                });
            }

            // don't shut the activity down and use provided path
            if (token.equals("take-picture-cont")) {
                final String path = ((StarwispActivity) ctx).m_AppDir + arr.getString(3);

                Log.i("starwisp", "take-picture-cont fired");

                v.TakePicture(new PictureCallback() {
                    public void onPictureTaken(byte[] input, Camera camera) {
                        Log.i("starwisp", "on picture taken...");

                        // the version used by the uav app

                        Bitmap original = BitmapFactory.decodeByteArray(input, 0, input.length);
                        //Bitmap resized = Bitmap.createScaledBitmap(original, PHOTO_WIDTH, PHOTO_HEIGHT, true);
                        ByteArrayOutputStream blob = new ByteArrayOutputStream();
                        original.compress(Bitmap.CompressFormat.JPEG, 95, blob);
                        original.recycle();
                        String filename = path;
                        Log.i("starwisp", path);
                        SaveData(filename, blob.toByteArray());

                        // burn gps into exif data
                        if (m_GPS.currentLocation != null) {
                            double latitude = m_GPS.currentLocation.getLatitude();
                            double longitude = m_GPS.currentLocation.getLongitude();

                            try {
                                ExifInterface exif = new ExifInterface(filename);
                                exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, GPS.convert(latitude));
                                exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF,
                                        GPS.latitudeRef(latitude));
                                exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, GPS.convert(longitude));
                                exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF,
                                        GPS.longitudeRef(longitude));
                                exif.saveAttributes();
                            } catch (IOException e) {
                                Log.i("starwisp",
                                        "Couldn't open " + filename + " to add exif data: ioexception caught.");
                            }

                        }

                        v.TakenPicture();
                    }
                });
            }

            if (token.equals("shutdown")) {
                v.Shutdown();
            }

            return;
        }

        if (type.equals("seek-bar")) {
            SeekBar v = new SeekBar(ctx);
            if (token.equals("max")) {
                // android seekbar bug workaround
                int p = v.getProgress();
                v.setMax(0);
                v.setProgress(0);
                v.setMax(arr.getInt(3));
                v.setProgress(1000);

                // not working.... :(
            }
        }

        if (type.equals("spinner")) {
            Spinner v = (Spinner) vv;

            if (token.equals("selection")) {
                v.setSelection(arr.getInt(3));
            }

            if (token.equals("array")) {
                final JSONArray items = arr.getJSONArray(3);
                ArrayList<String> spinnerArray = new ArrayList<String>();

                for (int i = 0; i < items.length(); i++) {
                    spinnerArray.add(items.getString(i));
                }

                ArrayAdapter spinnerArrayAdapter = new ArrayAdapter<String>(ctx, R.layout.spinner_item,
                        spinnerArray) {
                    public View getView(int position, View convertView, ViewGroup parent) {
                        View v = super.getView(position, convertView, parent);
                        ((TextView) v).setTypeface(((StarwispActivity) ctx).m_Typeface);
                        return v;
                    }
                };

                spinnerArrayAdapter.setDropDownViewResource(R.layout.spinner_layout);
                v.setAdapter(spinnerArrayAdapter);

                final int wid = id;
                // need to update for new values
                v.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                    public void onItemSelected(AdapterView<?> a, View v, int pos, long id) {
                        CallbackArgs(ctx, ctxname, wid, "" + pos);
                    }

                    public void onNothingSelected(AdapterView<?> v) {
                    }
                });

            }
            return;
        }

        if (type.equals("draw-map")) {
            DrawableMap v = m_DMaps.get(id);
            if (v != null) {
                if (token.equals("polygons")) {
                    v.UpdateFromJSON(arr.getJSONArray(3));
                }
                if (token.equals("centre")) {
                    JSONArray tokens = arr.getJSONArray(3);
                    v.Centre(tokens.getDouble(0), tokens.getDouble(1), tokens.getInt(2));
                }
                if (token.equals("layout")) {
                    v.m_parent.setLayoutParams(BuildLayoutParams(arr.getJSONArray(3)));
                }
            } else {
                Log.e("starwisp", "Asked to update a drawmap which doesn't exist");
            }
        }

    } catch (JSONException e) {
        Log.e("starwisp", "Error parsing builder data " + e.toString());
        Log.e("starwisp", "type:" + type + " id:" + id + " token:" + token);
    }
}