You should keep this limit low, especially if your pages have complex layouts.
+ * This setting defaults to 1.
+ *
+ * @param limit How many pages will be kept offscreen in an idle state.
+ */
+ public void setOffscreenPageLimit(int limit) {
+ if (limit < DEFAULT_OFFSCREEN_PAGES) {
+ Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " +
+ DEFAULT_OFFSCREEN_PAGES);
+ limit = DEFAULT_OFFSCREEN_PAGES;
+ }
+ if (limit != mOffscreenPageLimit) {
+ mOffscreenPageLimit = limit;
+ populate();
+ }
+ }
+
+ /**
+ * Set the margin between pages.
+ *
+ * @param marginPixels Distance between adjacent pages in pixels
+ * @see #getPageMargin()
+ * @see #setPageMarginDrawable(android.graphics.drawable.Drawable)
+ * @see #setPageMarginDrawable(int)
+ */
+ public void setPageMargin(int marginPixels) {
+ final int oldMargin = mPageMargin;
+ mPageMargin = marginPixels;
+
+ final int width = getWidth();
+ recomputeScrollPosition(width, width, marginPixels, oldMargin);
+
+ requestLayout();
+ }
+
+ /**
+ * Return the margin between pages.
+ *
+ * @return The size of the margin in pixels
+ */
+ public int getPageMargin() {
+ return mPageMargin;
+ }
+
+ /**
+ * Set a drawable that will be used to fill the margin between pages.
+ *
+ * @param d Drawable to display between pages
+ */
+ public void setPageMarginDrawable(Drawable d) {
+ mMarginDrawable = d;
+ if (d != null) refreshDrawableState();
+ setWillNotDraw(d == null);
+ invalidate();
+ }
+
+ /**
+ * Set a drawable that will be used to fill the margin between pages.
+ *
+ * @param resId Resource ID of a drawable to display between pages
+ */
+ public void setPageMarginDrawable(int resId) {
+ setPageMarginDrawable(getContext().getResources().getDrawable(resId));
+ }
+
+ @Override
+ protected boolean verifyDrawable(Drawable who) {
+ return super.verifyDrawable(who) || who == mMarginDrawable;
+ }
+
+ @Override
+ protected void drawableStateChanged() {
+ super.drawableStateChanged();
+ final Drawable d = mMarginDrawable;
+ if (d != null && d.isStateful()) {
+ d.setState(getDrawableState());
+ }
+ }
+
+ // We want the duration of the page snap animation to be influenced by the distance that
+ // the screen has to travel, however, we don't want this duration to be effected in a
+ // purely linear fashion. Instead, we use this method to moderate the effect that the distance
+ // of travel has on the overall snap duration.
+ float distanceInfluenceForSnapDuration(float f) {
+ f -= 0.5f; // center the values about 0.
+ f *= 0.3f * Math.PI / 2.0f;
+ return (float) Math.sin(f);
+ }
+
+ /**
+ * Like {@link android.view.View#scrollBy}, but scroll smoothly instead of immediately.
+ *
+ * @param x the number of pixels to scroll by on the X axis
+ * @param y the number of pixels to scroll by on the Y axis
+ */
+ void smoothScrollTo(int x, int y) {
+ smoothScrollTo(x, y, 0);
+ }
+
+ /**
+ * Like {@link android.view.View#scrollBy}, but scroll smoothly instead of immediately.
+ *
+ * @param x the number of pixels to scroll by on the X axis
+ * @param y the number of pixels to scroll by on the Y axis
+ * @param velocity the velocity associated with a fling, if applicable. (0 otherwise)
+ */
+ void smoothScrollTo(int x, int y, int velocity) {
+ if (getChildCount() == 0) {
+ // Nothing to do.
+ setScrollingCacheEnabled(false);
+ return;
+ }
+ int sx = getScrollX();
+ int sy = getScrollY();
+ int dx = x - sx;
+ int dy = y - sy;
+ if (dx == 0 && dy == 0) {
+ completeScroll();
+ setScrollState(SCROLL_STATE_IDLE);
+ return;
+ }
+
+ setScrollingCacheEnabled(true);
+ mScrolling = true;
+ setScrollState(SCROLL_STATE_SETTLING);
+
+ final float pageDelta = (float) Math.abs(dx) / (getWidth() + mPageMargin);
+ int duration = (int) (pageDelta * 100);
+
+ velocity = Math.abs(velocity);
+ if (velocity > 0) {
+ duration += (duration / (velocity / mBaseLineFlingVelocity)) * mFlingVelocityInfluence;
+ } else {
+ duration += 100;
+ }
+ duration = Math.min(duration, MAX_SETTLE_DURATION);
+
+ mScroller.startScroll(sx, sy, dx, dy, duration);
+ invalidate();
+ }
+
+ void addNewItem(int position, int index) {
+ ItemInfo ii = new ItemInfo();
+ ii.position = position;
+ ii.object = mAdapter.instantiateItem(this, position);
+ if (index < 0) {
+ mItems.add(ii);
+ } else {
+ mItems.add(index, ii);
+ }
+ }
+
+ void dataSetChanged() {
+ // This method only gets called if our observer is attached, so mAdapter is non-null.
+
+ boolean needPopulate = mItems.size() < 3 && mItems.size() < mAdapter.getCount();
+ int newCurrItem = -1;
+
+ for (int i = 0; i < mItems.size(); i++) {
+ final ItemInfo ii = mItems.get(i);
+ final int newPos = mAdapter.getItemPosition(ii.object);
+
+ if (newPos == PagerAdapter.POSITION_UNCHANGED) {
+ continue;
+ }
+
+ if (newPos == PagerAdapter.POSITION_NONE) {
+ mItems.remove(i);
+ i--;
+ mAdapter.destroyItem(this, ii.position, ii.object);
+ needPopulate = true;
+
+ if (mCurItem == ii.position) {
+ // Keep the current item in the valid range
+ newCurrItem = Math.max(0, Math.min(mCurItem, mAdapter.getCount() - 1));
+ }
+ continue;
+ }
+
+ if (ii.position != newPos) {
+ if (ii.position == mCurItem) {
+ // Our current item changed position. Follow it.
+ newCurrItem = newPos;
+ }
+
+ ii.position = newPos;
+ needPopulate = true;
+ }
+ }
+
+ Collections.sort(mItems, COMPARATOR);
+
+ if (newCurrItem >= 0) {
+ // TODO This currently causes a jump.
+ setCurrentItemInternal(newCurrItem, false, true);
+ needPopulate = true;
+ }
+ if (needPopulate) {
+ populate();
+ requestLayout();
+ }
+ }
+
+ void populate() {
+ if (mAdapter == null) {
+ return;
+ }
+
+ // Bail now if we are waiting to populate. This is to hold off
+ // on creating views from the time the user releases their finger to
+ // fling to a new position until we have finished the scroll to
+ // that position, avoiding glitches from happening at that point.
+ if (mPopulatePending) {
+ if (DEBUG) Log.i(UHFMainActivity.TAG, "populate is pending, skipping for now...");
+ return;
+ }
+
+ // Also, don't populate until we are attached to a window. This is to
+ // avoid trying to populate before we have restored our view hierarchy
+ // state and conflicting with what is restored.
+ if (getWindowToken() == null) {
+ return;
+ }
+
+ mAdapter.startUpdate(this);
+
+ final int pageLimit = mOffscreenPageLimit;
+ final int startPos = Math.max(0, mCurItem - pageLimit);
+ final int N = mAdapter.getCount();
+ final int endPos = Math.min(N-1, mCurItem + pageLimit);
+
+ if (DEBUG) Log.v(TAG, "populating: startPos=" + startPos + " endPos=" + endPos);
+
+ // Add and remove pages in the existing list.
+ int lastPos = -1;
+ for (int i=0; i endPos) && !ii.scrolling) {
+ if (DEBUG) Log.i(UHFMainActivity.TAG, "removing: " + ii.position + " @ " + i);
+ mItems.remove(i);
+ i--;
+ mAdapter.destroyItem(this, ii.position, ii.object);
+ } else if (lastPos < endPos && ii.position > startPos) {
+ // The next item is outside of our range, but we have a gap
+ // between it and the last item where we want to have a page
+ // shown. Fill in the gap.
+ lastPos++;
+ if (lastPos < startPos) {
+ lastPos = startPos;
+ }
+ while (lastPos <= endPos && lastPos < ii.position) {
+ if (DEBUG) Log.i(UHFMainActivity.TAG, "inserting: " + lastPos + " @ " + i);
+ addNewItem(lastPos, i);
+ lastPos++;
+ i++;
+ }
+ }
+ lastPos = ii.position;
+ }
+
+ // Add any new pages we need at the end.
+ lastPos = mItems.size() > 0 ? mItems.get(mItems.size()-1).position : -1;
+ if (lastPos < endPos) {
+ lastPos++;
+ lastPos = lastPos > startPos ? lastPos : startPos;
+ while (lastPos <= endPos) {
+ if (DEBUG) Log.i(UHFMainActivity.TAG, "appending: " + lastPos);
+ addNewItem(lastPos, -1);
+ lastPos++;
+ }
+ }
+
+ if (DEBUG) {
+ Log.i(UHFMainActivity.TAG, "Current page list:");
+ for (int i=0; i CREATOR
+ = ParcelableCompat.newCreator(new ParcelableCompatCreatorCallbacks() {
+ @Override
+ public SavedState createFromParcel(Parcel in, ClassLoader loader) {
+ return new SavedState(in, loader);
+ }
+ @Override
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ });
+
+ SavedState(Parcel in, ClassLoader loader) {
+ super(in);
+ if (loader == null) {
+ loader = getClass().getClassLoader();
+ }
+ position = in.readInt();
+ adapterState = in.readParcelable(loader);
+ this.loader = loader;
+ }
+ }
+
+ @Override
+ public Parcelable onSaveInstanceState() {
+ Parcelable superState = super.onSaveInstanceState();
+ SavedState ss = new SavedState(superState);
+ ss.position = mCurItem;
+ if (mAdapter != null) {
+ ss.adapterState = mAdapter.saveState();
+ }
+ return ss;
+ }
+
+ @Override
+ public void onRestoreInstanceState(Parcelable state) {
+ if (!(state instanceof SavedState)) {
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ SavedState ss = (SavedState)state;
+ super.onRestoreInstanceState(ss.getSuperState());
+
+ if (mAdapter != null) {
+ mAdapter.restoreState(ss.adapterState, ss.loader);
+ setCurrentItemInternal(ss.position, false, true);
+ } else {
+ mRestoredCurItem = ss.position;
+ mRestoredAdapterState = ss.adapterState;
+ mRestoredClassLoader = ss.loader;
+ }
+ }
+
+ @Override
+ public void addView(View child, int index, LayoutParams params) {
+ if (mInLayout) {
+ addViewInLayout(child, index, params);
+ child.measure(mChildWidthMeasureSpec, mChildHeightMeasureSpec);
+ } else {
+ super.addView(child, index, params);
+ }
+
+ if (USE_CACHE) {
+ if (child.getVisibility() != GONE) {
+ child.setDrawingCacheEnabled(mScrollingCacheEnabled);
+ } else {
+ child.setDrawingCacheEnabled(false);
+ }
+ }
+ }
+
+ ItemInfo infoForChild(View child) {
+ for (int i=0; i 0) {
+ final int oldScrollPos = getScrollX();
+ final int oldwwm = oldWidth + oldMargin;
+ final int oldScrollItem = oldScrollPos / oldwwm;
+ final float scrollOffset = (float) (oldScrollPos % oldwwm) / oldwwm;
+ final int scrollPos = (int) ((oldScrollItem + scrollOffset) * widthWithMargin);
+ scrollTo(scrollPos, getScrollY());
+ if (!mScroller.isFinished()) {
+ // We now return to your regularly scheduled scroll, already in progress.
+ final int newDuration = mScroller.getDuration() - mScroller.timePassed();
+ mScroller.startScroll(scrollPos, 0, mCurItem * widthWithMargin, 0, newDuration);
+ }
+ } else {
+ int scrollPos = mCurItem * widthWithMargin;
+ if (scrollPos != getScrollX()) {
+ completeScroll();
+ scrollTo(scrollPos, getScrollY());
+ }
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ mInLayout = true;
+ populate();
+ mInLayout = false;
+
+ final int count = getChildCount();
+ final int width = r-l;
+
+ for (int i = 0; i < count; i++) {
+ View child = getChildAt(i);
+ ItemInfo ii;
+ if (child.getVisibility() != GONE && (ii=infoForChild(child)) != null) {
+ int loff = (width + mPageMargin) * ii.position;
+ int childLeft = getPaddingLeft() + loff;
+ int childTop = getPaddingTop();
+ if (DEBUG) Log.v(TAG, "Positioning #" + i + " " + child + " f=" + ii.object
+ + ":" + childLeft + "," + childTop + " " + child.getMeasuredWidth()
+ + "x" + child.getMeasuredHeight());
+ child.layout(childLeft, childTop,
+ childLeft + child.getMeasuredWidth(),
+ childTop + child.getMeasuredHeight());
+ }
+ }
+ mFirstLayout = false;
+ }
+
+ @Override
+ public void computeScroll() {
+ if (DEBUG) Log.i(UHFMainActivity.TAG, "computeScroll: finished=" + mScroller.isFinished());
+ if (!mScroller.isFinished()) {
+ if (mScroller.computeScrollOffset()) {
+ if (DEBUG) Log.i(UHFMainActivity.TAG, "computeScroll: still scrolling");
+ int oldX = getScrollX();
+ int oldY = getScrollY();
+ int x = mScroller.getCurrX();
+ int y = mScroller.getCurrY();
+
+ if (oldX != x || oldY != y) {
+ scrollTo(x, y);
+ }
+
+ if (mOnPageChangeListener != null) {
+ final int widthWithMargin = getWidth() + mPageMargin;
+ final int position = x / widthWithMargin;
+ final int offsetPixels = x % widthWithMargin;
+ final float offset = (float) offsetPixels / widthWithMargin;
+ mOnPageChangeListener.onPageScrolled(position, offset, offsetPixels);
+ }
+
+ // Keep on drawing until the animation has finished.
+ invalidate();
+ return;
+ }
+ }
+
+ // Done with scroll, clean up state.
+ completeScroll();
+ }
+
+ private void completeScroll() {
+ boolean needPopulate = mScrolling;
+ if (needPopulate) {
+ // Done with scroll, no longer want to cache view drawing.
+ setScrollingCacheEnabled(false);
+ mScroller.abortAnimation();
+ int oldX = getScrollX();
+ int oldY = getScrollY();
+ int x = mScroller.getCurrX();
+ int y = mScroller.getCurrY();
+ if (oldX != x || oldY != y) {
+ scrollTo(x, y);
+ }
+ setScrollState(SCROLL_STATE_IDLE);
+ }
+ mPopulatePending = false;
+ mScrolling = false;
+ for (int i=0; i 0 && scrollX == 0) || (dx < 0 && mAdapter != null &&
+ scrollX >= (mAdapter.getCount() - 1) * getWidth() - 1);
+ if (DEBUG) Log.v(UHFMainActivity.TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff);
+
+ if (canScroll(this, false, (int) dx, (int) x, (int) y)) {
+ // Nested view has scrollable area under this point. Let it be handled there.
+ mInitialMotionX = mLastMotionX = x;
+ mLastMotionY = y;
+ return false;
+ }
+ if (xDiff > mTouchSlop && xDiff > yDiff) {
+ if (DEBUG) Log.v(UHFMainActivity.TAG, "Starting drag!");
+ mIsBeingDragged = true;
+ setScrollState(SCROLL_STATE_DRAGGING);
+ mLastMotionX = x;
+ setScrollingCacheEnabled(true);
+ } else {
+ if (yDiff > mTouchSlop) {
+ // The finger has moved enough in the vertical
+ // direction to be counted as a drag... abort
+ // any attempt to drag horizontally, to work correctly
+ // with children that have scrolling containers.
+ if (DEBUG) Log.v(UHFMainActivity.TAG, "Starting unable to drag!");
+ mIsUnableToDrag = true;
+ }
+ }
+ break;
+ }
+
+ case MotionEvent.ACTION_DOWN: {
+ /*
+ * Remember location of down touch.
+ * ACTION_DOWN always refers to pointer index 0.
+ */
+ mLastMotionX = mInitialMotionX = ev.getX();
+ mLastMotionY = ev.getY();
+ mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
+
+ if (mScrollState == SCROLL_STATE_SETTLING) {
+ // Let the user 'catch' the pager as it animates.
+ mIsBeingDragged = true;
+ mIsUnableToDrag = false;
+ setScrollState(SCROLL_STATE_DRAGGING);
+ } else {
+ completeScroll();
+ mIsBeingDragged = false;
+ mIsUnableToDrag = false;
+ }
+
+ if (DEBUG) Log.v(UHFMainActivity.TAG, "Down at " + mLastMotionX + "," + mLastMotionY
+ + " mIsBeingDragged=" + mIsBeingDragged
+ + "mIsUnableToDrag=" + mIsUnableToDrag);
+ break;
+ }
+
+ case MotionEventCompat.ACTION_POINTER_UP:
+ onSecondaryPointerUp(ev);
+ break;
+ }
+
+ /*
+ * The only time we want to intercept motion events is if we are in the
+ * drag mode.
+ */
+ return mIsBeingDragged;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ if (mFakeDragging) {
+ // A fake drag is in progress already, ignore this real one
+ // but still eat the touch events.
+ // (It is likely that the user is multi-touching the screen.)
+ return true;
+ }
+
+ if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
+ // Don't handle edge touches immediately -- they may actually belong to one of our
+ // descendants.
+ return false;
+ }
+
+ if (mAdapter == null || mAdapter.getCount() == 0) {
+ // Nothing to present or scroll; nothing to touch.
+ return false;
+ }
+
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+ mVelocityTracker.addMovement(ev);
+
+ final int action = ev.getAction();
+ boolean needsInvalidate = false;
+
+ switch (action & MotionEventCompat.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN: {
+ /*
+ * If being flinged and user touches, stop the fling. isFinished
+ * will be false if being flinged.
+ */
+ completeScroll();
+
+ // Remember where the motion event started
+ mLastMotionX = mInitialMotionX = ev.getX();
+ mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
+ break;
+ }
+ case MotionEvent.ACTION_MOVE:
+ if (!mIsBeingDragged) {
+ final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
+ final float x = MotionEventCompat.getX(ev, pointerIndex);
+ final float xDiff = Math.abs(x - mLastMotionX);
+ final float y = MotionEventCompat.getY(ev, pointerIndex);
+ final float yDiff = Math.abs(y - mLastMotionY);
+ if (DEBUG) Log.v(UHFMainActivity.TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff);
+ if (xDiff > mTouchSlop && xDiff > yDiff) {
+ if (DEBUG) Log.v(TAG, "Starting drag!");
+ mIsBeingDragged = true;
+ mLastMotionX = x;
+ setScrollState(SCROLL_STATE_DRAGGING);
+ setScrollingCacheEnabled(true);
+ }
+ }
+ if (mIsBeingDragged) {
+ // Scroll to follow the motion event
+ final int activePointerIndex = MotionEventCompat.findPointerIndex(
+ ev, mActivePointerId);
+ final float x = MotionEventCompat.getX(ev, activePointerIndex);
+ final float deltaX = mLastMotionX - x;
+ mLastMotionX = x;
+ float oldScrollX = getScrollX();
+ float scrollX = oldScrollX + deltaX;
+ final int width = getWidth();
+ final int widthWithMargin = width + mPageMargin;
+
+ final int lastItemIndex = mAdapter.getCount() - 1;
+ final float leftBound = Math.max(0, (mCurItem - 1) * widthWithMargin);
+ final float rightBound =
+ Math.min(mCurItem + 1, lastItemIndex) * widthWithMargin;
+ if (scrollX < leftBound) {
+ if (leftBound == 0) {
+ float over = -scrollX;
+ needsInvalidate = mLeftEdge.onPull(over / width);
+ }
+ scrollX = leftBound;
+ } else if (scrollX > rightBound) {
+ if (rightBound == lastItemIndex * widthWithMargin) {
+ float over = scrollX - rightBound;
+ needsInvalidate = mRightEdge.onPull(over / width);
+ }
+ scrollX = rightBound;
+ }
+ // Don't lose the rounded component
+ mLastMotionX += scrollX - (int) scrollX;
+ scrollTo((int) scrollX, getScrollY());
+ if (mOnPageChangeListener != null) {
+ final int position = (int) scrollX / widthWithMargin;
+ final int positionOffsetPixels = (int) scrollX % widthWithMargin;
+ final float positionOffset = (float) positionOffsetPixels / widthWithMargin;
+ mOnPageChangeListener.onPageScrolled(position, positionOffset,
+ positionOffsetPixels);
+ }
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ if (mIsBeingDragged) {
+ final VelocityTracker velocityTracker = mVelocityTracker;
+ velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+ int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(
+ velocityTracker, mActivePointerId);
+ mPopulatePending = true;
+ final int widthWithMargin = getWidth() + mPageMargin;
+ final int scrollX = getScrollX();
+ final int currentPage = scrollX / widthWithMargin;
+ int nextPage = initialVelocity > 0 ? currentPage : currentPage + 1;
+ setCurrentItemInternal(nextPage, true, true, initialVelocity);
+
+ mActivePointerId = INVALID_POINTER;
+ endDrag();
+ needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease();
+ }
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ if (mIsBeingDragged) {
+ setCurrentItemInternal(mCurItem, true, true);
+ mActivePointerId = INVALID_POINTER;
+ endDrag();
+ needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease();
+ }
+ break;
+ case MotionEventCompat.ACTION_POINTER_DOWN: {
+ final int index = MotionEventCompat.getActionIndex(ev);
+ final float x = MotionEventCompat.getX(ev, index);
+ mLastMotionX = x;
+ mActivePointerId = MotionEventCompat.getPointerId(ev, index);
+ break;
+ }
+ case MotionEventCompat.ACTION_POINTER_UP:
+ onSecondaryPointerUp(ev);
+ mLastMotionX = MotionEventCompat.getX(ev,
+ MotionEventCompat.findPointerIndex(ev, mActivePointerId));
+ break;
+ }
+ if (needsInvalidate) {
+ invalidate();
+ }
+ return true;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+ boolean needsInvalidate = false;
+
+ final int overScrollMode = ViewCompat.getOverScrollMode(this);
+ if (overScrollMode == ViewCompat.OVER_SCROLL_ALWAYS ||
+ (overScrollMode == ViewCompat.OVER_SCROLL_IF_CONTENT_SCROLLS &&
+ mAdapter != null && mAdapter.getCount() > 1)) {
+ if (!mLeftEdge.isFinished()) {
+ final int restoreCount = canvas.save();
+ final int height = getHeight() - getPaddingTop() - getPaddingBottom();
+
+ canvas.rotate(270);
+ canvas.translate(-height + getPaddingTop(), 0);
+ mLeftEdge.setSize(height, getWidth());
+ needsInvalidate |= mLeftEdge.draw(canvas);
+ canvas.restoreToCount(restoreCount);
+ }
+ if (!mRightEdge.isFinished()) {
+ final int restoreCount = canvas.save();
+ final int width = getWidth();
+ final int height = getHeight() - getPaddingTop() - getPaddingBottom();
+ final int itemCount = mAdapter != null ? mAdapter.getCount() : 1;
+
+ canvas.rotate(90);
+ canvas.translate(-getPaddingTop(), -itemCount * (width + mPageMargin) + mPageMargin);
+ mRightEdge.setSize(height, width);
+ needsInvalidate |= mRightEdge.draw(canvas);
+ canvas.restoreToCount(restoreCount);
+ }
+ } else {
+ mLeftEdge.finish();
+ mRightEdge.finish();
+ }
+
+ if (needsInvalidate) {
+ // Keep animating
+ invalidate();
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ // Draw the margin drawable if needed.
+ if (mPageMargin > 0 && mMarginDrawable != null) {
+ final int scrollX = getScrollX();
+ final int width = getWidth();
+ final int offset = scrollX % (width + mPageMargin);
+ if (offset != 0) {
+ // Pages fit completely when settled; we only need to draw when in between
+ final int left = scrollX - offset + width;
+ mMarginDrawable.setBounds(left, 0, left + mPageMargin, getHeight());
+ mMarginDrawable.draw(canvas);
+ }
+ }
+ }
+
+ /**
+ * Start a fake drag of the pager.
+ *
+ *
A fake drag can be useful if you want to synchronize the motion of the ViewPager
+ * with the touch scrolling of another view, while still letting the ViewPager
+ * control the snapping motion and fling behavior. (e.g. parallax-scrolling tabs.)
+ * Call {@link #fakeDragBy(float)} to simulate the actual drag motion. Call
+ * {@link #endFakeDrag()} to complete the fake drag and fling as necessary.
+ *
+ *
During a fake drag the ViewPager will ignore all touch events. If a real drag
+ * is already in progress, this method will return false.
+ *
+ * @return true if the fake drag began successfully, false if it could not be started.
+ *
+ * @see #fakeDragBy(float)
+ * @see #endFakeDrag()
+ */
+ public boolean beginFakeDrag() {
+ if (mIsBeingDragged) {
+ return false;
+ }
+ mFakeDragging = true;
+ setScrollState(SCROLL_STATE_DRAGGING);
+ mInitialMotionX = mLastMotionX = 0;
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ } else {
+ mVelocityTracker.clear();
+ }
+ final long time = SystemClock.uptimeMillis();
+ final MotionEvent ev = MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, 0, 0, 0);
+ mVelocityTracker.addMovement(ev);
+ ev.recycle();
+ mFakeDragBeginTime = time;
+ return true;
+ }
+
+ /**
+ * End a fake drag of the pager.
+ *
+ * @see #beginFakeDrag()
+ * @see #fakeDragBy(float)
+ */
+ public void endFakeDrag() {
+ if (!mFakeDragging) {
+ throw new IllegalStateException("No fake drag in progress. Call beginFakeDrag first.");
+ }
+
+ final VelocityTracker velocityTracker = mVelocityTracker;
+ velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+ int initialVelocity = (int)VelocityTrackerCompat.getYVelocity( velocityTracker, mActivePointerId);
+ mPopulatePending = true;
+ if ((Math.abs(initialVelocity) > mMinimumVelocity)
+ || Math.abs(mInitialMotionX-mLastMotionX) >= (getWidth()/3)) {
+ if (mLastMotionX > mInitialMotionX) {
+ setCurrentItemInternal(mCurItem-1, true, true);
+ } else {
+ setCurrentItemInternal(mCurItem+1, true, true);
+ }
+ } else {
+ setCurrentItemInternal(mCurItem, true, true);
+ }
+ endDrag();
+
+ mFakeDragging = false;
+ }
+
+ /**
+ * Fake drag by an offset in pixels. You must have called {@link #beginFakeDrag()} first.
+ *
+ * @param xOffset Offset in pixels to drag by.
+ * @see #beginFakeDrag()
+ * @see #endFakeDrag()
+ */
+ public void fakeDragBy(float xOffset) {
+ if (!mFakeDragging) {
+ throw new IllegalStateException("No fake drag in progress. Call beginFakeDrag first.");
+ }
+
+ mLastMotionX += xOffset;
+ float scrollX = getScrollX() - xOffset;
+ final int width = getWidth();
+ final int widthWithMargin = width + mPageMargin;
+
+ final float leftBound = Math.max(0, (mCurItem - 1) * widthWithMargin);
+ final float rightBound = Math.min(mCurItem + 1, mAdapter.getCount() - 1) * widthWithMargin;
+ if (scrollX < leftBound) {
+ scrollX = leftBound;
+ } else if (scrollX > rightBound) {
+ scrollX = rightBound;
+ }
+ // Don't lose the rounded component
+ mLastMotionX += scrollX - (int) scrollX;
+ scrollTo((int) scrollX, getScrollY());
+ if (mOnPageChangeListener != null) {
+ final int position = (int) scrollX / widthWithMargin;
+ final int positionOffsetPixels = (int) scrollX % widthWithMargin;
+ final float positionOffset = (float) positionOffsetPixels / widthWithMargin;
+ mOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
+ }
+
+ // Synthesize an event for the VelocityTracker.
+ final long time = SystemClock.uptimeMillis();
+ final MotionEvent ev = MotionEvent.obtain(mFakeDragBeginTime, time, MotionEvent.ACTION_MOVE,
+ mLastMotionX, 0, 0);
+ mVelocityTracker.addMovement(ev);
+ ev.recycle();
+ }
+
+ /**
+ * Returns true if a fake drag is in progress.
+ *
+ * @return true if currently in a fake drag, false otherwise.
+ *
+ * @see #beginFakeDrag()
+ * @see #fakeDragBy(float)
+ * @see #endFakeDrag()
+ */
+ public boolean isFakeDragging() {
+ return mFakeDragging;
+ }
+
+ private void onSecondaryPointerUp(MotionEvent ev) {
+ final int pointerIndex = MotionEventCompat.getActionIndex(ev);
+ final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // This was our active pointer going up. Choose a new
+ // active pointer and adjust accordingly.
+ final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+ mLastMotionX = MotionEventCompat.getX(ev, newPointerIndex);
+ mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
+ if (mVelocityTracker != null) {
+ mVelocityTracker.clear();
+ }
+ }
+ }
+
+ private void endDrag() {
+ mIsBeingDragged = false;
+ mIsUnableToDrag = false;
+
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ }
+
+ private void setScrollingCacheEnabled(boolean enabled) {
+ if (mScrollingCacheEnabled != enabled) {
+ mScrollingCacheEnabled = enabled;
+ if (USE_CACHE) {
+ final int size = getChildCount();
+ for (int i = 0; i < size; ++i) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() != GONE) {
+ child.setDrawingCacheEnabled(enabled);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Tests scrollability within child views of v given a delta of dx.
+ *
+ * @param v View to test for horizontal scrollability
+ * @param checkV Whether the view v passed should itself be checked for scrollability (true),
+ * or just its children (false).
+ * @param dx Delta scrolled in pixels
+ * @param x X coordinate of the active touch point
+ * @param y Y coordinate of the active touch point
+ * @return true if child views of v can be scrolled by delta of dx.
+ */
+ protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
+ if (v instanceof ViewGroup) {
+ final ViewGroup group = (ViewGroup) v;
+ final int scrollX = v.getScrollX();
+ final int scrollY = v.getScrollY();
+ final int count = group.getChildCount();
+ // Count backwards - let topmost views consume scroll distance first.
+ for (int i = count - 1; i >= 0; i--) {
+ // TODO: Add versioned support here for transformed views.
+ // This will not work for transformed views in Honeycomb+
+ final View child = group.getChildAt(i);
+ if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight() &&
+ y + scrollY >= child.getTop() && y + scrollY < child.getBottom() &&
+ canScroll(child, true, dx, x + scrollX - child.getLeft(),
+ y + scrollY - child.getTop())) {
+ return true;
+ }
+ }
+ }
+
+ return checkV && ViewCompat.canScrollHorizontally(v, -dx);
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ // Let the focused view and/or our descendants get the key first
+ return super.dispatchKeyEvent(event) || executeKeyEvent(event);
+ }
+
+ /**
+ * You can call this function yourself to have the scroll view perform
+ * scrolling from a key event, just as if the event had been dispatched to
+ * it by the view hierarchy.
+ *
+ * @param event The key event to execute.
+ * @return Return true if the event was handled, else false.
+ */
+ public boolean executeKeyEvent(KeyEvent event) {
+ boolean handled = false;
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ switch (event.getKeyCode()) {
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ handled = arrowScroll(FOCUS_LEFT);
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ handled = arrowScroll(FOCUS_RIGHT);
+ break;
+ case KeyEvent.KEYCODE_TAB:
+ if (event.hasNoModifiers()) {
+ handled = arrowScroll(FOCUS_FORWARD);
+ } else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) {
+ handled = arrowScroll(FOCUS_BACKWARD);
+ }
+ break;
+ }
+ }
+ return handled;
+ }
+
+ public boolean arrowScroll(int direction) {
+ View currentFocused = findFocus();
+ if (currentFocused == this) currentFocused = null;
+
+ boolean handled = false;
+
+ View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused,
+ direction);
+ if (nextFocused != null && nextFocused != currentFocused) {
+ if (direction == View.FOCUS_LEFT) {
+ // If there is nothing to the left, or this is causing us to
+ // jump to the right, then what we really want to do is page left.
+ if (currentFocused != null && nextFocused.getLeft() >= currentFocused.getLeft()) {
+ handled = pageLeft();
+ } else {
+ handled = nextFocused.requestFocus();
+ }
+ } else if (direction == View.FOCUS_RIGHT) {
+ // If there is nothing to the right, or this is causing us to
+ // jump to the left, then what we really want to do is page right.
+ if (currentFocused != null && nextFocused.getLeft() <= currentFocused.getLeft()) {
+ handled = pageRight();
+ } else {
+ handled = nextFocused.requestFocus();
+ }
+ }
+ } else if (direction == FOCUS_LEFT || direction == FOCUS_BACKWARD) {
+ // Trying to move left and nothing there; try to page.
+ handled = pageLeft();
+ } else if (direction == FOCUS_RIGHT || direction == FOCUS_FORWARD) {
+ // Trying to move right and nothing there; try to page.
+ handled = pageRight();
+ }
+ if (handled) {
+ playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction));
+ }
+ return handled;
+ }
+
+ boolean pageLeft() {
+ if (mCurItem > 0) {
+ setCurrentItem(mCurItem-1, true);
+ return true;
+ }
+ return false;
+ }
+
+ boolean pageRight() {
+ if (mAdapter != null && mCurItem < (mAdapter.getCount()-1)) {
+ setCurrentItem(mCurItem+1, true);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * We only want the current page that is being shown to be focusable.
+ */
+ @Override
+ public void addFocusables(ArrayList views, int direction, int focusableMode) {
+ final int focusableCount = views.size();
+
+ final int descendantFocusability = getDescendantFocusability();
+
+ if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) {
+ for (int i = 0; i < getChildCount(); i++) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() == VISIBLE) {
+ ItemInfo ii = infoForChild(child);
+ if (ii != null && ii.position == mCurItem) {
+ child.addFocusables(views, direction, focusableMode);
+ }
+ }
+ }
+ }
+
+ // we add ourselves (if focusable) in all cases except for when we are
+ // FOCUS_AFTER_DESCENDANTS and there are some descendants focusable. this is
+ // to avoid the focus search finding layouts when a more precise search
+ // among the focusable children would be more interesting.
+ if (
+ descendantFocusability != FOCUS_AFTER_DESCENDANTS ||
+ // No focusable descendants
+ (focusableCount == views.size())) {
+ // Note that we can't call the superclass here, because it will
+ // add all views in. So we need to do the same thing View does.
+ if (!isFocusable()) {
+ return;
+ }
+ if ((focusableMode & FOCUSABLES_TOUCH_MODE) == FOCUSABLES_TOUCH_MODE &&
+ isInTouchMode() && !isFocusableInTouchMode()) {
+ return;
+ }
+ if (views != null) {
+ views.add(this);
+ }
+ }
+ }
+
+ /**
+ * We only want the current page that is being shown to be touchable.
+ */
+ @Override
+ public void addTouchables(ArrayList views) {
+ // Note that we don't call super.addTouchables(), which means that
+ // we don't call View.addTouchables(). This is okay because a ViewPager
+ // is itself not touchable.
+ for (int i = 0; i < getChildCount(); i++) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() == VISIBLE) {
+ ItemInfo ii = infoForChild(child);
+ if (ii != null && ii.position == mCurItem) {
+ child.addTouchables(views);
+ }
+ }
+ }
+ }
+
+ /**
+ * We only want the current page that is being shown to be focusable.
+ */
+ @Override
+ protected boolean onRequestFocusInDescendants(int direction,
+ Rect previouslyFocusedRect) {
+ int index;
+ int increment;
+ int end;
+ int count = getChildCount();
+ if ((direction & FOCUS_FORWARD) != 0) {
+ index = 0;
+ increment = 1;
+ end = count;
+ } else {
+ index = count - 1;
+ increment = -1;
+ end = -1;
+ }
+ for (int i = index; i != end; i += increment) {
+ View child = getChildAt(i);
+ if (child.getVisibility() == VISIBLE) {
+ ItemInfo ii = infoForChild(child);
+ if (ii != null && ii.position == mCurItem) {
+ if (child.requestFocus(direction, previouslyFocusedRect)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ // ViewPagers should only report accessibility info for the current page,
+ // otherwise things get very confusing.
+
+ // TODO: Should this note something about the paging container?
+
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() == VISIBLE) {
+ final ItemInfo ii = infoForChild(child);
+ if (ii != null && ii.position == mCurItem &&
+ child.dispatchPopulateAccessibilityEvent(event)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private class PagerObserver extends DataSetObserver {
+
+ @Override
+ public void onChanged() {
+ dataSetChanged();
+ }
+
+ @Override
+ public void onInvalidated() {
+ dataSetChanged();
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/uhf/widget/NoScrollViewPager.java b/app/src/main/java/com/example/uhf/widget/NoScrollViewPager.java
new file mode 100644
index 0000000..42bfbc9
--- /dev/null
+++ b/app/src/main/java/com/example/uhf/widget/NoScrollViewPager.java
@@ -0,0 +1,58 @@
+package com.example.uhf.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+/**
+ * Created by Administrator on 2021/6/22.
+ */
+public class NoScrollViewPager extends LazyViewPager {
+ private boolean noScroll = true;
+
+ public NoScrollViewPager(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ // TODO Auto-generated constructor stub
+ }
+
+ public NoScrollViewPager(Context context) {
+ super(context);
+ }
+
+ public void setNoScroll(boolean noScroll) {
+ this.noScroll = noScroll;
+ }
+
+ @Override
+ public void scrollTo(int x, int y) {
+ super.scrollTo(x, y);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent arg0) {
+ /* return false;//super.onTouchEvent(arg0); */
+ if (noScroll)
+ return false;
+ else
+ return super.onTouchEvent(arg0);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent arg0) {
+ if (noScroll)
+ return false;
+ else
+ return super.onInterceptTouchEvent(arg0);
+ }
+
+ @Override
+ public void setCurrentItem(int item, boolean smoothScroll) {
+ super.setCurrentItem(item, smoothScroll);
+ }
+
+ @Override
+ public void setCurrentItem(int item) {
+ super.setCurrentItem(item);
+ }
+
+}
diff --git a/app/src/main/jniLibs/arm64-v8a/libIGLBarDecoder.so b/app/src/main/jniLibs/arm64-v8a/libIGLBarDecoder.so
new file mode 100644
index 0000000..5a93842
Binary files /dev/null and b/app/src/main/jniLibs/arm64-v8a/libIGLBarDecoder.so differ
diff --git a/app/src/main/jniLibs/arm64-v8a/libIGLImageAE.so b/app/src/main/jniLibs/arm64-v8a/libIGLImageAE.so
new file mode 100644
index 0000000..b09a1dd
Binary files /dev/null and b/app/src/main/jniLibs/arm64-v8a/libIGLImageAE.so differ
diff --git a/app/src/main/jniLibs/armeabi-v7a/libIGLBarDecoder.so b/app/src/main/jniLibs/armeabi-v7a/libIGLBarDecoder.so
new file mode 100644
index 0000000..6f829ad
Binary files /dev/null and b/app/src/main/jniLibs/armeabi-v7a/libIGLBarDecoder.so differ
diff --git a/app/src/main/jniLibs/armeabi-v7a/libIGLImageAE.so b/app/src/main/jniLibs/armeabi-v7a/libIGLImageAE.so
new file mode 100644
index 0000000..a1a5003
Binary files /dev/null and b/app/src/main/jniLibs/armeabi-v7a/libIGLImageAE.so differ
diff --git a/app/src/main/res/anim/grow_from_topleft_to_bottomright.xml b/app/src/main/res/anim/grow_from_topleft_to_bottomright.xml
new file mode 100644
index 0000000..b172ebe
--- /dev/null
+++ b/app/src/main/res/anim/grow_from_topleft_to_bottomright.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/app/src/main/res/anim/slide_left_in.xml b/app/src/main/res/anim/slide_left_in.xml
new file mode 100644
index 0000000..7c2a16e
--- /dev/null
+++ b/app/src/main/res/anim/slide_left_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/app/src/main/res/anim/slide_left_out.xml b/app/src/main/res/anim/slide_left_out.xml
new file mode 100644
index 0000000..b82cf26
--- /dev/null
+++ b/app/src/main/res/anim/slide_left_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/app/src/main/res/anim/slide_right_in.xml b/app/src/main/res/anim/slide_right_in.xml
new file mode 100644
index 0000000..d0a781c
--- /dev/null
+++ b/app/src/main/res/anim/slide_right_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/app/src/main/res/anim/slide_right_out.xml b/app/src/main/res/anim/slide_right_out.xml
new file mode 100644
index 0000000..f78757f
--- /dev/null
+++ b/app/src/main/res/anim/slide_right_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/app/src/main/res/drawable-hdpi/close.png b/app/src/main/res/drawable-hdpi/close.png
new file mode 100644
index 0000000..70e9316
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/close.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_launcher.png b/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..288b665
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/drawable-hdpi/webtext.png b/app/src/main/res/drawable-hdpi/webtext.png
new file mode 100644
index 0000000..3e95210
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/webtext.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_launcher.png b/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..6ae570b
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_launcher.png b/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..d4fb7cd
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..85a6081
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/drawable/actionbar_back.xml b/app/src/main/res/drawable/actionbar_back.xml
new file mode 100644
index 0000000..4993b82
--- /dev/null
+++ b/app/src/main/res/drawable/actionbar_back.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/button_bg.xml b/app/src/main/res/drawable/button_bg.xml
new file mode 100644
index 0000000..626413e
--- /dev/null
+++ b/app/src/main/res/drawable/button_bg.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/button_bg2.xml b/app/src/main/res/drawable/button_bg2.xml
new file mode 100644
index 0000000..e8b2643
--- /dev/null
+++ b/app/src/main/res/drawable/button_bg2.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/button_bg3.xml b/app/src/main/res/drawable/button_bg3.xml
new file mode 100644
index 0000000..5725149
--- /dev/null
+++ b/app/src/main/res/drawable/button_bg3.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/button_bg_down.xml b/app/src/main/res/drawable/button_bg_down.xml
new file mode 100644
index 0000000..06bd38f
--- /dev/null
+++ b/app/src/main/res/drawable/button_bg_down.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/button_bg_down2.xml b/app/src/main/res/drawable/button_bg_down2.xml
new file mode 100644
index 0000000..5c3e699
--- /dev/null
+++ b/app/src/main/res/drawable/button_bg_down2.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/button_bg_down3.xml b/app/src/main/res/drawable/button_bg_down3.xml
new file mode 100644
index 0000000..e318978
--- /dev/null
+++ b/app/src/main/res/drawable/button_bg_down3.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/button_bg_gray.xml b/app/src/main/res/drawable/button_bg_gray.xml
new file mode 100644
index 0000000..b099120
--- /dev/null
+++ b/app/src/main/res/drawable/button_bg_gray.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/button_bg_up.xml b/app/src/main/res/drawable/button_bg_up.xml
new file mode 100644
index 0000000..d0591a6
--- /dev/null
+++ b/app/src/main/res/drawable/button_bg_up.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/button_bg_up2.xml b/app/src/main/res/drawable/button_bg_up2.xml
new file mode 100644
index 0000000..da4250c
--- /dev/null
+++ b/app/src/main/res/drawable/button_bg_up2.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/button_bg_up3.xml b/app/src/main/res/drawable/button_bg_up3.xml
new file mode 100644
index 0000000..246f66b
--- /dev/null
+++ b/app/src/main/res/drawable/button_bg_up3.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/card_normal.xml b/app/src/main/res/drawable/card_normal.xml
new file mode 100644
index 0000000..b83aa79
--- /dev/null
+++ b/app/src/main/res/drawable/card_normal.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/card_press.xml b/app/src/main/res/drawable/card_press.xml
new file mode 100644
index 0000000..306804f
--- /dev/null
+++ b/app/src/main/res/drawable/card_press.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/check_text_color.xml b/app/src/main/res/drawable/check_text_color.xml
new file mode 100644
index 0000000..ad3a302
--- /dev/null
+++ b/app/src/main/res/drawable/check_text_color.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/check_text_color2.xml b/app/src/main/res/drawable/check_text_color2.xml
new file mode 100644
index 0000000..210d6fe
--- /dev/null
+++ b/app/src/main/res/drawable/check_text_color2.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/rb_bg.xml b/app/src/main/res/drawable/rb_bg.xml
new file mode 100644
index 0000000..3e381b5
--- /dev/null
+++ b/app/src/main/res/drawable/rb_bg.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/rectangle_bg.xml b/app/src/main/res/drawable/rectangle_bg.xml
new file mode 100644
index 0000000..f3e961c
--- /dev/null
+++ b/app/src/main/res/drawable/rectangle_bg.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/rectangle_bg2.xml b/app/src/main/res/drawable/rectangle_bg2.xml
new file mode 100644
index 0000000..55a23fe
--- /dev/null
+++ b/app/src/main/res/drawable/rectangle_bg2.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..34a3af7
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_uhfset.xml b/app/src/main/res/layout/activity_uhfset.xml
new file mode 100644
index 0000000..b9da269
--- /dev/null
+++ b/app/src/main/res/layout/activity_uhfset.xml
@@ -0,0 +1,617 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_blank.xml b/app/src/main/res/layout/fragment_blank.xml
new file mode 100644
index 0000000..89b0518
--- /dev/null
+++ b/app/src/main/res/layout/fragment_blank.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_deactivate.xml b/app/src/main/res/layout/fragment_deactivate.xml
new file mode 100644
index 0000000..4cd1a23
--- /dev/null
+++ b/app/src/main/res/layout/fragment_deactivate.xml
@@ -0,0 +1,197 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml
new file mode 100644
index 0000000..15c8880
--- /dev/null
+++ b/app/src/main/res/layout/fragment_main.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/item_text1.xml b/app/src/main/res/layout/item_text1.xml
new file mode 100644
index 0000000..9c4353d
--- /dev/null
+++ b/app/src/main/res/layout/item_text1.xml
@@ -0,0 +1,10 @@
+
+
diff --git a/app/src/main/res/layout/listtag_items.xml b/app/src/main/res/layout/listtag_items.xml
new file mode 100644
index 0000000..d6bf7f0
--- /dev/null
+++ b/app/src/main/res/layout/listtag_items.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/popwindow_filter.xml b/app/src/main/res/layout/popwindow_filter.xml
new file mode 100644
index 0000000..a016c37
--- /dev/null
+++ b/app/src/main/res/layout/popwindow_filter.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/uhf_dialog_frequency.xml b/app/src/main/res/layout/uhf_dialog_frequency.xml
new file mode 100644
index 0000000..8f91778
--- /dev/null
+++ b/app/src/main/res/layout/uhf_dialog_frequency.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/uhf_dialog_lock_code.xml b/app/src/main/res/layout/uhf_dialog_lock_code.xml
new file mode 100644
index 0000000..6cb390e
--- /dev/null
+++ b/app/src/main/res/layout/uhf_dialog_lock_code.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/uhf_kill_fragment.xml b/app/src/main/res/layout/uhf_kill_fragment.xml
new file mode 100644
index 0000000..e5c6dbb
--- /dev/null
+++ b/app/src/main/res/layout/uhf_kill_fragment.xml
@@ -0,0 +1,183 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/uhf_lock_fragment.xml b/app/src/main/res/layout/uhf_lock_fragment.xml
new file mode 100644
index 0000000..47bd2ca
--- /dev/null
+++ b/app/src/main/res/layout/uhf_lock_fragment.xml
@@ -0,0 +1,205 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/uhf_read_fragment.xml b/app/src/main/res/layout/uhf_read_fragment.xml
new file mode 100644
index 0000000..1d6f41b
--- /dev/null
+++ b/app/src/main/res/layout/uhf_read_fragment.xml
@@ -0,0 +1,329 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/uhf_readtag_fragment.xml b/app/src/main/res/layout/uhf_readtag_fragment.xml
new file mode 100644
index 0000000..fc49047
--- /dev/null
+++ b/app/src/main/res/layout/uhf_readtag_fragment.xml
@@ -0,0 +1,212 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/uhf_write_fragment.xml b/app/src/main/res/layout/uhf_write_fragment.xml
new file mode 100644
index 0000000..c67187e
--- /dev/null
+++ b/app/src/main/res/layout/uhf_write_fragment.xml
@@ -0,0 +1,264 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml
new file mode 100644
index 0000000..40ac07d
--- /dev/null
+++ b/app/src/main/res/menu/main.xml
@@ -0,0 +1,42 @@
+
\ No newline at end of file
diff --git a/app/src/main/res/raw/barcodebeep.ogg b/app/src/main/res/raw/barcodebeep.ogg
new file mode 100644
index 0000000..ca1532c
Binary files /dev/null and b/app/src/main/res/raw/barcodebeep.ogg differ
diff --git a/app/src/main/res/raw/serror.ogg b/app/src/main/res/raw/serror.ogg
new file mode 100644
index 0000000..8cc359a
Binary files /dev/null and b/app/src/main/res/raw/serror.ogg differ
diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..f3e7020
--- /dev/null
+++ b/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,10 @@
+
+
+
+ 64dp
+
+
diff --git a/app/src/main/res/values-zh/messages.xml b/app/src/main/res/values-zh/messages.xml
new file mode 100644
index 0000000..6c76728
--- /dev/null
+++ b/app/src/main/res/values-zh/messages.xml
@@ -0,0 +1,71 @@
+
+
+ 网络连接失败,请检查网络设置
+ 数据解析异常
+ 文件流异常
+ 网络异常,错误码:%d
+ 网络异常,请求超时
+ 网络异常,读取数据超时
+ 应用程序运行时异常
+
+ 确定退出程序吗?
+ 确定
+ 取消
+
+ 应用程序错误
+ 很抱歉,应用程序出现错误,即将退出。\n请提交错误报告,我们会尽快修复这个问题!
+ 提交报告
+
+ 更多
+ 加载中···
+ 已加载全部
+ 暂无数据
+ 加载数据出错
+
+ 有 %d 条更新
+ 没有新更新
+
+ 选择
+ 分享
+ 分享中...
+ 发布中...
+ 请选择图片文件!
+ 确定删除该图片吗?
+ 确定删除该动弹吗?
+ 确定删除该博客吗?
+ 网络超时,是否重新发布动弹?
+ 清除文字吗?
+
+ 读取失败,可能已被删除
+ 无效的邮箱地址
+ 请输入用户名
+ 请输入密码
+ 登录成功
+ 登录失败
+ 退出成功
+ 用户未登录 或 密码错误
+ 用户头像加载失败
+ 图片加载失败
+ 无法获取文章信息
+ 您没有删除权限
+
+
+ 账号不能为空
+ 密码不能为空
+ 服务器验证中...
+
+
+ 服务器验证失败
+ 第三方应用验证成功
+ 第三方应用验证失败
+ 用户授权登录成功
+ 用户授权登录失败
+ 授权已过期,请重新授权登录
+ 分享数据不能为空
+ 已超出140个字
+ 微博分享成功
+ 微博分享失败
+ 已经分享过了
+
+ 正文字体
+
diff --git a/app/src/main/res/values-zh/msg.xml b/app/src/main/res/values-zh/msg.xml
new file mode 100644
index 0000000..f15204d
--- /dev/null
+++ b/app/src/main/res/values-zh/msg.xml
@@ -0,0 +1,60 @@
+
+
+ 设备配置错误
+ 初始化失败
+ 密钥长度应为12位
+ 内容请输入十六进制数
+ 密码不能为空
+ 锁定码不能为空
+ 销毁失败
+ 销毁成功
+ 锁定成功
+ 锁定失败
+ 不能使用默认密码销毁
+ 不能使用默认密码锁定
+ 提示:永久锁定之后,无法解锁;永久解锁后,无法锁定
+ 密钥验证失败
+ 寻卡失败
+ \nUID:
+ \n卡片类型:
+ \n数据:
+ \n读卡失败
+ \n读卡成功
+ \n写卡失败
+ \n写卡成功
+ 0扇区的0数据块是不能写入
+ 写入内容不能为空
+ 此程序不支持该数据块的写入操作,该数据块是密码控制块
+ 数据应该是一个字节
+ 确定吗?
+ 确定
+ 取消
+ 操作之后,该标签的AFI将不能再次修改!, 要锁住AFI吗?
+ 操作之后,该标签的DSFID将不能再次修改!, 要锁住AFI吗?
+ \n锁定失败
+ \n锁定成功
+
+ 读取标签号失败
+ 地址不能为空
+ 地址必须为十进制数据
+ 访问密码的长度必须为8位
+ 写入数据不能为空
+ 写入数据的字符串长度必须为4位
+ 标签号不能为空
+ 写入数据成功
+ 写入数据失败
+ 长度不能为空
+ 长度必须为十进制数据
+ 写入数据的字符串长度必须为4的倍数
+ 读取数据失败
+
+ 识别失败
+ 停止识别标签失败
+ 开启识别标签失败
+ 设置频率失败
+ 设置频率成功
+ 读取频率失败
+ 读取频率成功
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-zh/rfid.xml b/app/src/main/res/values-zh/rfid.xml
new file mode 100644
index 0000000..25a23b2
--- /dev/null
+++ b/app/src/main/res/values-zh/rfid.xml
@@ -0,0 +1,14 @@
+
+
+
+ S50
+ S70
+
+
+
+ A
+ B
+
+
+
+
diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml
new file mode 100644
index 0000000..7d84845
--- /dev/null
+++ b/app/src/main/res/values-zh/strings.xml
@@ -0,0 +1,1173 @@
+
+
+
+ demo_uhf
+ 设置
+ 关于
+ 显示设置
+ 输入域名/IP
+ PING次数
+ PING成功
+ PING失败
+ 秒
+ 后台运行
+ 超时时间(秒)
+ 开始
+ 重新开始
+ Ping 结果
+ 上传 结果
+ 下载 结果
+ 停止
+ 设置
+ 设置
+ 无网络,请先打开网络
+ 网络已连接
+ 无网络
+ 域名/IP格式错误
+ 加载中...
+ 无数据
+ 错误
+ 变化
+ 不匹配
+ AppCenter
+ 再按一次退出
+ 上传测速 %s
+ 下载测速 %s
+ 返回
+ 确定
+ 退出
+ 保存
+ 取消
+ 清除
+ 关闭
+ ..(返回上一级目录)
+ .(刷新)
+ 文件路径
+ 浏览...
+ 无权限访问该目录
+ 下载测速
+ 上传测速
+ Ping测试
+ 下载测速
+ 上传测速
+ 上传
+ 升级
+ PingActivity
+ Hello world!
+ 数据包大小
+ Ping测试 %s
+ 一维条码测试
+ 二维条码测试
+ 一维条码
+ 二维条码
+ 扫描
+ 清除
+ 初始条码
+ 执行间隔
+ 工作
+ 等待
+ 比较
+ 连续,间隔
+ 读取失败
+
+
+ 扫描已取消
+ 扫描超时
+
+
+
+ 条码不正确
+ 扫描次数
+ 成功次数
+ 失败次数
+ 错误次数
+ 错误率
+ 成功率
+ 失败率
+ 蓝牙打印
+
+ 解码时间
+
+
+
+ 发送
+ 打印
+ 清空
+ 请先连接蓝牙打印机
+ 蓝牙没有启动,不能打单据
+ 正在连接...
+ 已连接:
+ 没有连接
+ 4
+ 打印灰度
+ (1~8)
+ HELLO WORLD! \n
+
+
+
+ 扫描设备...
+ 选择连接的设备
+ 没有匹配的设备
+ 没有找到设备
+ 匹配的设备
+ 其它可用设备
+ 扫描设备
+ UHF
+
+
+ 识别标签
+ 标签数
+ 单步
+ 循环
+ 防碰撞
+ Q值:
+ 开始识别
+ 停止识别
+ 标签
+ 长度
+ 数量
+ 清空数据
+ 导出
+ 标签
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+
+
+ ID卡
+ 动物标签
+ HiTag
+ HDX标签
+ EM4450
+ HID PROXIMITY
+
+
+ 读标签号
+ 指定标签
+ 标 签 号:
+ 存 储 区:
+ 地 址:
+ 长度:
+ 访问密码:
+ 锁定码:
+ 读取模式:
+ 循环
+ 防碰撞
+ 2级参数设置
+ 存 储 区:
+ 地 址:
+ 长 度:
+ 数据内容:
+ 读取数据
+
+
+ RESERVED
+ EPC
+ TID
+ USER
+
+
+ EPC
+ TID
+ USER
+
+
+ 单次读
+ 循环读
+ 防碰撞读(1级)
+ 防碰撞读(2级)
+
+
+
+ 输出功率:
+ 设置功率
+ 设置空占比
+ 获取空占比
+ 读取功率
+ dBm
+
+
+ 链路参数:
+ 设置链路
+ 读取链路
+
+
+ 读
+ 写
+
+ 过滤
+
+ 临时掩码
+ 永久掩码
+ 开放
+ 锁
+
+ Session ID
+ Inventoried Flag
+ 获取 Session
+ 设置 Session
+
+ 请选择UII的去向
+ 读取数据
+ 写入数据
+ 擦除数据
+ 锁定数据
+ 确定
+ 取消
+
+
+ 标签列表
+ 读取UII
+
+
+ 停止
+ 返回
+
+
+ 标签号:
+ 存储区:
+ 地址:
+ 长度:
+ 次数:
+ 数据:
+ 状态:
+
+
+ 标 签 号:
+ 写入模式:
+ 写入数据:
+ 写入数据
+
+
+ 单字单次
+ 多字单次
+
+
+
+ 标 签 号:
+ KillPwd:
+ AccessPwd:
+ UII:
+ TID:
+ USER:
+ 锁 定 码:
+ 生成
+ 锁定
+
+
+ 保持状态
+ 锁定
+ 解锁
+ 永久锁定
+ 永久解锁
+
+
+ S0
+ S1
+ S2
+ S3
+
+
+ A
+ B
+
+
+ 标 签 号:
+ 销毁密码:
+ 销毁
+
+
+ 存储区:
+ 地 址:
+ 掩 码:
+ 序 号:
+ 数量:
+ 添加
+ 删除
+ 选择
+ 读取
+
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+
+
+
+
+ R2000功能
+
+
+ 协议(仅R2000):
+ 开启寻隐藏区(QT标签):
+
+ 开启寻TID和EPC:
+ 开启FastID:
+ 开启TagFocus:
+
+
+ 工作模式:
+ 设置频率
+ 设置协议
+ 设置频点
+
+ QT标签
+ 设置QT参数
+ 获取QT参数
+
+
+
+ 频点:
+ 频率范围:
+ 读取频率
+ 起始频率整数:
+ 840
+ +
+ -
+ 起始频率小数:
+ 50
+ +
+ -
+ 频率基数:
+ 频道数:
+ 频道数不小于1
+ 频道带宽:
+ 跳频方式:
+ 计算
+ MHz
+ KHz
+
+
+ 中国标准(920~925MHz)
+ 中国标准(840~845MHz)
+ ETSI标准(865~868MHz)
+ 定频模式(915MHz)
+ 美国标准(902~928MHz)
+
+
+ 0
+ 1
+
+
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+
+
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+
+
+ 随机跳频
+ 从高往低顺序跳频
+ 从低往高顺序跳频
+
+
+ 5V
+ 3V
+ 1.8V
+ iso
+
+
+ 9600
+ 19200
+ 38400
+ 43000
+ 56000
+ 57600
+ 115200
+
+
+ 设置
+ 网络信号
+ 通道
+ 等级
+ 子网掩码
+ 状态
+ TestActivity
+ 已连接:
+ 暂停
+ 继续
+ WiFi个数:
+ 连接到
+ BSSID:
+ 安全:
+ 密码:
+ IP地址:
+ 运营商:
+ 状态:
+ 网络类型:
+ 信号强度:
+ GPS
+ 经度:
+ 纬度:
+ 连接卫星数:
+ 海拔:
+ GPS状态:
+ 定位耗时:
+ 全局设置
+ 14443A
+ 15693
+ 标签类型:
+
+ 常规
+ 自动
+
+ 密钥类型:
+ 密钥:
+ 扇区:
+ 块:
+ 读取
+ 写入
+ UID:
+ 扫描标签
+ AFI(1 Byte)
+ DSFID(1 Byte)
+ 读取ID
+ 写入
+ 锁定
+ 写入
+ 锁定
+ 连续读写
+ 连续读
+ 连续写
+ 连续读写
+ 总次数:
+ 读卡成功次数:
+ 读卡失败次数:
+ 写卡成功次数:
+ 写卡失败次数:
+ RFID版本
+
+ PSAM版本
+
+
+ 升级固件
+
+ 升级固件
+
+
+ UHF版本
+ 指纹模块版本
+ 内存:
+ 存储:
+ 分辨率:
+ 设备型号:
+ Android版本:
+ 系统版本:
+ 内核版本:
+ jar版本:
+ MAC:
+ 序列号:
+ IMEI:
+ 请选择功能模块...
+ 按键测试
+ 电\n源\n键
+ HOME键
+ 返回键
+ 正在 Ping
+ Ping已终止,域名/IP错误
+ 网络未连接
+ 请先选择文件
+ 文件不存在
+ 文件大小:
+ 开始时间:
+ 结束时间:
+ 上传耗时:
+ 平均速度:
+ 下载文件
+ 确认下载该文件?
+ 确定
+ 取消
+ 关闭
+ 文件路径不存在
+ 下载成功
+ 下载失败
+ 上传成功
+ 上传失败
+ 测试结果
+ 下载大小:
+ 下载耗时:
+ SD不存在
+ 正在下载 ...
+ 正在上传 ...
+ 上传被取消
+ 下载被取消
+ 设备不支持蓝牙
+ 蜂窝数据
+ 无Sim卡信息
+ 仅限紧急呼叫
+ 信号正常
+ 不在服务区
+ 断电
+ WiFi连接失败
+ WiFi连接中...
+ WiFi不可用
+ 连接
+ 速度:
+ 等级:
+ 请开启GPS导航...
+ 定位成功
+ 正在定位...
+ 定位结束
+ 卫星信号
+ 扫描
+ 读数据
+ 写数据
+ 设置
+ 销毁
+ 锁定
+ 扫描失败
+ 连续扫描
+ Ping
+ 正在ping,完成后点击查看结果
+ 完成
+ 文件
+ 电量监视
+
+
+ 重启测试
+
+
+
+ 提示:结果保存在SD卡的handset/BatteryMonitor目录中
+ 电量监视
+
+ 系统默认
+ 自定义
+
+
+ 电量监视中...
+ 未在充电
+ 充电状态
+ 放电状态
+ 未充电
+ 充满电
+ 未知道状态
+ 未知错误
+ 状态良好
+ 电池没有电
+ 电池电压过高
+ 电池过热
+ 主电池电量为
+ 电压为
+ 温度为
+ 手柄电池电量为:
+ 手柄电池电流为:
+
+
+ 指纹识别
+ 识别
+ 采集
+ 存储ID
+ 模式
+ 默认
+ ISO
+ 用户名称
+ 提示
+ 是否确定清空?
+ 确定
+ 取消
+ 指纹采集
+ 停止采集
+ 指纹识别
+ 存储ID不能为空
+ 用户名称不能为空
+ 存储ID必须为数字
+ 存储ID必须0~254范围内
+ 采集成功
+ 采集失败
+ 图片
+ 图片(ISO)
+ 自动
+ 获取指纹图片失败
+ 模块初始化失败
+
+ RFID升级失败
+ RFID升级成功
+
+ PSAM升级失败
+ PSAM升级成功
+
+
+ 认证失败
+ 认证成功
+ 匹配得分
+ 数据
+ 设置
+ 导入模块
+ 重置模块
+ 导入失败(succ:%1$d,fail:%2$d)
+ 导入成功
+ 您确定要重置吗?
+ 重置失败
+ 重置成功
+ 序号
+ 页ID
+ 名称
+ 采集时间
+ 本地指纹数:
+ 模块指纹数:
+ 删除
+ 清空
+
+ 设置口令
+ 验证口令
+ 口令
+
+ 比对阀值
+ 包大小
+
+ 设置阀值
+ 获取阀值
+
+
+ 设置波特率
+ 获取波特率
+
+ 重新初始化
+
+ 设置包大小
+ 获取包大小
+
+
+ 设置比对阀值成功
+ 设置比对阀值失败
+
+ 设置波特率成功
+ 设置比波特率失败
+
+
+ 设置包大小成功
+ 设置比包大小失败
+
+
+ 设置密码成功
+ 设置比密码失败
+
+
+ 验证密码成功
+ 验证密码失败
+
+ 无运营商信息
+ 选择文件
+ 确认选择该文件?
+ 确定
+ 取消
+ 取消选择
+ 不能为空
+ 提示
+ GPS未打开,是否去打开?
+ 是
+ 否
+ 提示
+ 没有已配对的蓝牙设备,请先去配对。
+ 是
+ 否
+ 连接失败,请检查设备是否被占用
+ 标签类型:
+ 读取失败
+ 页ID:
+ 数据:
+ 写入
+ 读取
+ 数据不能为空
+ 请输入4字节HEX
+ 写入成功
+ 写入失败
+ 只能在0,3,5~13,其中一页写入数据
+ RFID_LF
+ 针管标签
+ 音量设置
+ 通话音量
+ 系统音量
+ 铃声音量
+ 音乐音量
+ 提示声音音量
+ 闹铃音量
+ 正在初始化模块...
+
+
+ 升级中...\n请勿退出,以免损坏硬件!
+
+
+ 传感器
+ 打开
+ 自动
+ 停止
+ 关闭
+ 红
+ 绿
+ 蓝
+ 指示灯
+ 传感器
+ 屏幕亮度
+
+ 陀螺仪
+ 指南针
+
+ 距离传感器值:
+ 光线传感器值:
+ 打开辅助灯
+ 关闭辅助灯
+ 打开辅助灯失败
+ 关闭辅助灯失败
+ 请选择功能模块
+ 北斗
+ 定位成功
+ 正在定位...
+ 定位结束
+ 卫星信号
+ 经度:
+ 纬度:
+ 连接卫星数:
+ 海拔:
+ 状态:
+ 定位耗时:
+ GPS
+ BD
+ GPS & BD
+ 冷启动
+ 温启动
+ 热启动
+ 14443A CPU
+ 命令
+ 数据
+ 初始化
+ 发送
+ 获取UID
+ 自动
+ 停止
+ RATS和PPS出错
+ CPU卡号
+ RATS返回码
+ 命令发送出错
+ 获取卡号失败
+ 获取UID失败
+ UID:
+ 14443B
+ 初始化失败
+ 初始化返回数据
+ 命令返回数据
+ 无法下载安装文件,请检查SD卡是否挂载
+ 正在检测,请稍后...
+ 系统提示
+ 您当前已经是最新版本
+ 无法获取版本更新信息
+ 确定
+ 取消
+ 软件版本更新
+ 立即更新
+ 以后再说
+ 正在下载新版本
+ PSAM
+ 电 压
+ 参数
+ 波特率
+ 命令
+ 数据
+ 发送
+ 设置
+ 清除
+
+
+ 保存记录
+
+ 卡槽1
+ 卡槽2
+
+
+ 记录保存在handset/PSAM目录.
+
+ 操作失败
+ 模拟通话
+ 按住录音
+ 松开播放
+ 相机
+ 设备只有一个摄像头!
+ 切换摄像头
+ 设备没有摄像头!
+
+
+ 相机扫码
+ 应用
+ 书签
+ 添加事件至日历
+ 添加联系人
+ 返回
+ 打开图书搜索
+ 取消
+ 自定义搜索
+ 拨号
+ 完成
+ 发送email
+ 获取地址
+ 谷歌购物
+ 发送彩信
+ 确定
+ 打开浏览器
+ 打开产品搜索
+ 搜索图书内容
+ 共享应用
+ 分享书签
+ 通过email分享
+ 通过短信分享
+ 分享剪切板
+ 分享联系人
+ 显示地图
+ 发送短信
+ 网页搜索
+ 连接到网络
+ 联系人信息
+ Email地址
+ 地理坐标
+ 电话号码
+ 短信地址
+ 纯文本
+ 删除
+ 删除历史
+ 条码扫描器历史
+ 空的
+ 没有条码扫描已记录
+ 发送历史
+ 历史
+ 使用MECARD
+ 使用vCard
+ 帮助
+ 历史
+ 设置
+ 分享
+ 批量扫描:找到条码,已保存
+ 抱歉,Android相机出现问题。您可能需要重启设备。
+ 格式
+ 元数据
+ Hi
+ 请将条码置于取景框内扫描。
+ 时间
+ 类型
+ 无法根据已有数据生成条码。
+ 谷歌图书
+ 谷歌购物
+ 谷歌购物未安装
+ 谷歌购物是一款将条码扫描和商品比价相结合的应用,谷歌购物不使用浏览器,您想尝试吗?
+ 抱歉,无法打开所需软件。 条码内容可能无效。
+ 重定向
+ 抱歉,无法找到此图书。
+ 抱歉,搜索时遇到错误。
+ 无页面返回
+ 页面
+ 结果
+ 搜索图书…
+ 摘录不可用
+ 未知页面
+ 您可以通过在自己的手机上显示条码,并使用其它手机扫描此条码的方式进行分享
+ 这是我所扫描条码的内容
+ 或键入一些文字
+ 你肯定吗?
+ 抱歉,SD卡不可访问。
+ 找到条码时
+ 使用自动对焦
+ 连续扫描并保存多个条形码
+ 批量扫描模式
+ 复制到剪切板
+ 替换:%s=内容,%f=格式,%t=类型
+ 自定义搜索网址
+ 扫描 一维条码
+ 扫描 DM码
+ 扫描 QR码
+ 设备问题解决办法
+ 只使用标准对焦模式
+ 没有持续关注
+ 无曝光
+ 前灯可用时,打开前灯
+ 前灯
+ 一般设置
+ 设置
+ 提示音
+ 在历史记录中保存重复记录
+ 记住重复
+ 结果设置
+ 条码类型选择
+ 搜索国家
+ 尝试检索关于条码内容的更多信息
+ 检索更多信息
+ 尝试条码扫描器+
+ 增强新的功能和接口
+ 振动
+ 找到联系人信息
+ 找到日历事件
+ 找到email地址
+ 找到地理坐标
+ 找到图书
+ 找到产品
+ 找到短信地址
+ 找到电话号码
+ 找到纯文本
+ 找到URL
+ 发现网络配置
+ Google图书搜索
+ 通过条码分享
+ 请求连接到网络\u2026
+ 网络SSID
+ 类型
+
+
+
+
+ 自动网络测试
+
+ 寻卡
+ 上一级
+ 密码
+ 1~6位十六进制数
+ 密码不能为空
+ 属性
+ 改密码
+ 版本
+ 新建应用
+ 格式化
+ 删除
+ 新建文件
+ 选择应用失败
+ 请输入十六进制数
+ 验证失败
+ 获取应用失败
+ 获取文件失败
+
+ 获取信息失败
+ 密码属性可修改
+ 增删应用验证密码
+ 操作应用验证密码
+ 密码可修改
+
+ 操作失败
+ 操作成功
+
+ 应用ID
+ 文件个数
+ 通讯设置
+ 创建
+ 修改
+
+ 3个字节十六进制数
+ 应用ID必须是3个字节
+ 文件数必须是1个字节
+ 通讯设置必须是1个字节
+ 文件号
+ 文件大小
+ 通讯加密
+
+
+
+ 透明传输
+ 3DES加密传输
+
+ 读权
+ 写权
+ 读写
+ 改设
+
+ 文件已满
+ 文件大小不能为空
+ 数据文件
+ 值文件
+
+ 最小
+ 最大
+ 当前
+ 不能为空
+ 剩余金额
+ 充值金额
+ 扣除金额
+
+ 数据
+ 卡片属性
+ 卡片版本
+ 未知类型文件
+
+ 修改应用密码
+ 应用属性
+ 提示
+ 是否确认操作?
+
+ 增删文件验证密码
+ 操作文件验证密码
+ 改变应用密码所需权限
+ 最大密钥数
+ 点击进入
+
+
+ 按键广播
+ 设备不支持NFC!
+ 请在系统设置中先启用NFC功能!
+
+ 将手机背面靠近NFC标签开始写入
+
+ 读取
+ 写入
+ NFC Tag是只读的!
+ 写入内容过长
+ 标签写入成功
+ 标签不支持NDEF
+ 出现异常,写入失败
+ 打印机
+ 打印机缺纸
+
+
+ 简易键盘
+ 全键盘
+ 二维(软解)
+ 扫描
+ 拍照
+ 设置
+
+ 获取图像数据失败
+ 已保存图片到相册
+
+ 获取
+ 设置
+
+ 设置成功
+ 设置失败
+
+
+ 设置
+ 条码扫描设置
+ 启用松开按键关闭扫描
+ 红外
+ 串口测试
+ 接收的内容
+
+ 重启次数:
+ 已完成:
+ 设定数:
+
+ 位置:
+
+ 十六进制
+
+ 打开失败
+ 打开成功
+
+ 关闭失败
+ 关闭成功
+
+ 文件格式不正确
+
+ 校验:
+ 电能值
+ 97标准
+ 07标准
+ 耗时
+ 电表号
+
+
+
+ 菜单
+ 公共模块设置
+ R2000专用设置
+ 设置链路参数
+ 获取链路参数
+ 开启tagFocus
+ 开启FastID
+ 开启寻EPC和TID
+ 关闭tagFocus
+ 关闭FastID
+ 关闭寻EPC和TID
+ 擦除
+ 请输入存储的数据
+ 设置协议成功
+ 设置协议失败
+ 设置QT参数成功
+ 设置QT参数失败
+ 获取QT参数成功
+ 获取QT参数失败
+ 请先开启QT标签
+ 启用
+ 禁用
+ 禁用成功
+ 禁用失败
+ 数据格式不对
+ 标签号格式不对
+ 此功能仅对R2000模块有效设置协议成功
+ 设置协议失败
+
+ 设置频点成功
+ 设置频点失败
+
+ 设置成功
+ 设置失败
+
+ 获取成功
+ 获取失败
+
+
+ 读取空占比失败
+ 设置空占比成功
+ 设置空占比失败
+
+ 设置过滤失败
+ 设置过滤成功
+
+ 设置功率失败
+ 设置功率成功
+ 读取功率失败
+ 读取功率成功
+
+ 中国
+ 欧洲
+ 美国
+ 其他
+ 频点类型:
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
new file mode 100644
index 0000000..5133e3a
--- /dev/null
+++ b/app/src/main/res/values/arrays.xml
@@ -0,0 +1,35 @@
+
+
+
+ -
+ AR
+ AU
+ BR
+ BG
+ CA
+ CN
+ CZ
+ DE
+ DK
+ ES
+ FI
+ FR
+ GB
+ GR
+ HU
+ ID
+ IT
+ JP
+ KR
+ NL
+ PL
+ PT
+ RU
+ SE
+ SK
+ SI
+ TR
+ TW
+ US
+
+
diff --git a/app/src/main/res/values/attrs_card_view.xml b/app/src/main/res/values/attrs_card_view.xml
new file mode 100644
index 0000000..1e6ab5d
--- /dev/null
+++ b/app/src/main/res/values/attrs_card_view.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..eb4abf5
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,100 @@
+
+
+
+
+ #FFFFFF
+ #eeeeee
+ #000000
+ #313a4d
+ #808080
+ #dbdbdb
+ #ababab
+ #ededed
+ #FF0000
+ #db2627
+ #db2829
+ #22FF0000
+ #88FF0000
+ #aaFF0000
+ #FFD700
+ #FFFF00
+ #008000
+ #22008000
+ #88008000
+ #aa008000
+ #0000FF
+ #2095ac
+ #2398bc
+ #800080
+ #FFC0CB
+ #FFA500
+ #FFFACD
+ #F5F5F5
+ #708090
+ #0083FF
+ #CCCCCC
+ #00000000
+ #aa000000
+
+ #ff000000
+ #ff9da19e
+
+ #ff3f3f3f
+ #ff999999
+
+
+ #ff2c2c2e
+ #ff999999
+ #ffb1b1b1
+ #ffffffff
+ #ff39393b
+ #00000000
+
+
+ #ff000000
+ #ffffffff
+ #ffcccccc
+ #ff404040
+ #c0ffff00
+ #ffffffff
+ #ffc0c0c0
+ #c000ff00
+ #ffffffff
+ #b0000000
+ #ff808080
+ #ffffffff
+ #fffff0e0
+ #ffffffff
+ #ff000000
+ #ff4b4b4b
+ #ff000000
+ #ffffffff
+ #00000000
+ #ff000000
+ #ffff0000
+ #60000000
+
+
+
+
+ #99cc00
+ #33b5e5
+ #0099cc
+ #547bca
+ #aa66cc
+ #9933cc
+ #669900
+ #aeb857
+ #cc0000
+ #df5948
+ #ff4444
+ #ae6b23
+ #ff8800
+ #e5ae4f
+ #ffbb33
+ #cccccc
+ #888888
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..0afdc11
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,58 @@
+
+
+ 8dip
+ 4dip
+
+
+
+ 16dp
+ 16dp
+
+ 32.0dip
+ 31.0dip
+ 30.0dip
+ 29.0dip
+ 28.0dip
+ 27.0dip
+ 26.0dip
+ 25.0dip
+ 24.0dip
+ 23.0dip
+ 22.0dip
+ 21.0dip
+ 20.0dip
+ 19.0dip
+ 18.0dip
+ 17.0dip
+ 16.0dip
+ 15.0dip
+ 14.0dip
+ 13.0dip
+ 12.0dip
+ 11.0dip
+ 10.0dip
+ 9.0dip
+ 8.0dip
+ 7.0dip
+
+
+ 60dp
+ 10dp
+ 0dp
+
+ 1
+ 50.0dip
+
+
+ 14.0sp
+ 42.0dip
+ 14.0sp
+ 14.0sp
+ 12.0sp
+ 14.0sp
+ 2.0dip
+ 18.0sp
+ 44.0dip
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/fileendings.xml b/app/src/main/res/values/fileendings.xml
new file mode 100644
index 0000000..2e8a1ce
--- /dev/null
+++ b/app/src/main/res/values/fileendings.xml
@@ -0,0 +1,37 @@
+
+
+
+
+ .png
+ .gif
+ .jpg
+ .jpeg
+ .bmp
+
+
+ .mp3
+ .wav
+ .ogg
+ .midi
+ .wma
+
+
+ .jar
+ .zip
+ .rar
+ .gz
+
+
+ .htm
+ .html
+ .php
+
+
+ .mp4
+ .rm
+ .mpg
+ .avi
+ .mpeg
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml
new file mode 100644
index 0000000..8983150
--- /dev/null
+++ b/app/src/main/res/values/ids.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/messages.xml b/app/src/main/res/values/messages.xml
new file mode 100644
index 0000000..840aca4
--- /dev/null
+++ b/app/src/main/res/values/messages.xml
@@ -0,0 +1,71 @@
+
+
+ Network connection failed, please check the network Settings
+ Abnormal data parsing
+ Document flow anomalies
+ Network anomalies, error code:%d
+ Network anomalies, request timeout
+ Network anomalies, read data timeout
+ Application runtime exception
+
+ Determine the exit?
+ OK
+ Cancel
+
+ App Error
+ I am very sorry, application error, the exit \n Please submit a bug report, we will fix the problem as soon as possible
+ 提交报告
+
+ 更多
+ 加载中···
+ 已加载全部
+ 暂无数据
+ 加载数据出错
+
+ 有 %d 条更新
+ 没有新更新
+
+ 选择
+ 分享
+ 分享中...
+ 发布中...
+ 请选择图片文件!
+ 确定删除该图片吗?
+ 确定删除该动弹吗?
+ 确定删除该博客吗?
+ 网络超时,是否重新发布动弹?
+ 清除文字吗?
+
+ 读取失败,可能已被删除
+ 无效的邮箱地址
+ 请输入用户名
+ 请输入密码
+ 登录成功
+ 登录失败
+ 退出成功
+ 用户未登录 或 密码错误
+ 用户头像加载失败
+ 图片加载失败
+ 无法获取文章信息
+ 您没有删除权限
+
+
+ 账号不能为空
+ 密码不能为空
+ 服务器验证中...
+
+
+ 服务器验证失败
+ 第三方应用验证成功
+ 第三方应用验证失败
+ 用户授权登录成功
+ 用户授权登录失败
+ 授权已过期,请重新授权登录
+ 分享数据不能为空
+ 已超出140个字
+ 微博分享成功
+ 微博分享失败
+ 已经分享过了
+
+ 正文字体
+
diff --git a/app/src/main/res/values/model_arr.xml b/app/src/main/res/values/model_arr.xml
new file mode 100644
index 0000000..fadc381
--- /dev/null
+++ b/app/src/main/res/values/model_arr.xml
@@ -0,0 +1,221 @@
+
+
+
+
+ @string/title_Ping
+ @string/title_Upload
+ @string/title_Download
+ @string/title_activity_bluetooth_print
+ @string/title_activity_network_status
+ @string/title_activity_gps
+ @string/title_activity_battery_monitor
+
+
+ ping
+ updown
+ updown
+ bluetooth
+ network
+ gps
+ battery
+
+
+ PingActivity
+ UploadActivity
+ DownloadActivity
+ BluetoothPrintActivity
+ NetworkStatusActivity
+ GpsActivity
+ BatteryMonitorActivity
+
+
+ @string/title_Ping
+ @string/title_Upload
+ @string/title_Download
+ @string/title_activity_yi_d
+ @string/title_activity_bluetooth_print
+ @string/title_activity_key_test
+ @string/title_activity_network_status
+ @string/title_activity_gps
+ @string/title_activity_uhfmain
+ @string/title_activity_a1443
+ @string/title_activity_iso15693
+ @string/title_activity_lf
+ @string/title_activity_battery_monitor
+ @string/title_activity_fingerprint
+ @string/title_activity_volum
+ @string/title_activity_light_and_psensor
+
+
+ PingActivity
+ UploadActivity
+ DownloadActivity
+ YiDActivity
+ BluetoothPrintActivity
+ KeyTestActivity
+ NetworkStatusActivity
+ GpsActivity
+ UHFMainActivity
+ A14443Activity
+ ISO15693Activity
+ LFActivity
+ BatteryMonitorActivity
+ FingerprintActivity
+ VolumActivity
+ LightAndPSensorActivity
+
+
+ ping
+ updown
+ updown
+ d11
+ bluetooth
+ keyboard
+ network
+ gps
+ uhf
+ rfid
+ rfid
+ rfid
+ battery
+ fingerprint
+ volum
+ sensor
+
+
+ @string/title_activity_auto_run_network
+ @string/title_Ping
+ @string/title_Upload
+ @string/title_Download
+ @string/title_activity_yi_d
+ @string/title_activity_er_d
+ @string/title_activity_bluetooth_print
+ @string/title_activity_key_test
+ @string/title_activity_network_status
+ @string/title_activity_gps
+ @string/title_activity_analog_call
+ @string/title_activity_uhfmain
+ @string/title_activity_a1443
+ @string/title_activity_iso14443_a4_cpu
+ @string/title_activity_iso14443b
+ @string/title_activity_iso15693
+ @string/title_activity_lf
+ @string/title_activity_battery_monitor
+ @string/title_activity_fingerprint
+ @string/title_activity_volum
+ @string/title_activity_light_and_psensor
+ @string/title_activity_bdnav
+ @string/title_activity_psam
+ @string/title_activity_camera
+ @string/zxing_app_name
+
+
+ AutoRunNetworkActivity
+ PingActivity
+ UploadActivity
+ DownloadActivity
+ YiDActivity
+ ErDActivity
+ BluetoothPrintActivity
+ KeyTestActivity
+ NetworkStatusActivity
+ GpsActivity
+ AnalogCallActivity
+ UHFMainActivity
+ A14443Activity
+ ISO14443A4CPUActivity
+ ISO14443BActivity
+ ISO15693Activity
+ LFActivity
+ BatteryMonitorActivity
+ FingerprintActivity
+ VolumActivity
+ LightAndPSensorActivity
+ BDNavActivity
+ PSAMActivity
+ CameraActivity
+ CaptureActivity
+
+
+ n_autorun
+ n_ping
+ n_upload
+ n_download
+ n_d11
+ n_d22
+ n_bluetooth
+ n_keyboard
+ n_network
+ n_gps
+ n_call
+ n_rfid
+ n_rfid
+ n_rfid
+ n_rfid
+ n_rfid
+ n_rfid
+ n_battery
+ n_fingerprint
+ n_volum
+ n_sensor
+ n_beidou
+ n_psam
+ n_camera
+ n_qr
+
+
+ @string/title_Ping
+ @string/title_Upload
+ @string/title_Download
+ @string/title_activity_yi_d
+ @string/title_activity_bluetooth_print
+ @string/title_activity_uhfmain
+ @string/title_activity_network_status
+ @string/title_activity_gps
+ @string/title_activity_a1443
+ @string/title_activity_iso15693
+ @string/title_activity_lf
+ @string/title_activity_battery_monitor
+ @string/title_activity_fingerprint
+ @string/title_activity_volum
+ @string/title_activity_light_and_psensor
+ @string/title_activity_psam
+
+
+ PingActivity
+ UploadActivity
+ DownloadActivity
+ YiDActivity
+ BluetoothPrintActivity
+ UHFMainActivity
+ NetworkStatusActivity
+ GpsActivity
+ A14443Activity
+ ISO15693Activity
+ LFActivity
+ BatteryMonitorActivity
+ FingerprintActivity
+ VolumActivity
+ LightAndPSensorActivity
+ PSAMActivity
+
+
+ ping
+ updown
+ updown
+ d11
+ bluetooth
+ uhf
+ network
+ gps
+ rfid
+ rfid
+ rfid
+ battery
+ fingerprint
+ volum
+ sensor
+ psam
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/msg.xml b/app/src/main/res/values/msg.xml
new file mode 100644
index 0000000..4e870c0
--- /dev/null
+++ b/app/src/main/res/values/msg.xml
@@ -0,0 +1,68 @@
+
+
+
+ Device configuration error
+ Device initialization failed
+ The key length should be 12
+ Please enter the hexadecimal number content
+ Password cannot be empty
+ Lock code cannot be empty
+ Kill failure
+ Kill success
+ Lock success
+ Lock failure
+ Can\'t use the default password
+ Can\'t use the default password
+ Tips:After permanent lock, unable to unlock;After permanent unlock, not locked
+ The key validation fails
+ Find card failure
+ \nUID:
+ \nTag type:
+ \nData:
+ \nRead failure
+ \nRead success
+ \nWrite failure
+ \nWrite success
+ Sector 0 of 0 data block is read-only
+ Content to be written can not be empty
+ This program does not support the data block write operation, the data is password control block are not familiar with the tag structure please do not write to.
+ Data should be a byte
+ Are You Sure?
+ Confirm
+ Cancel
+ After the execution, the AFI of the tag will not be modified!\nlock AFI?
+ After the execution, the DSFID of the tag will not be modified!\nlock DSFID?
+ \nLock AFI failed
+ \nLock AFI success
+ Read the Tag failed
+ Address can\'t be empty
+ Address must be a decimal data
+ The length of the access password must be 8
+ Write data can not be empty
+ Write the length of the data string must be 4
+ EPC cannot be empty
+ Write data successfully
+ Write data failure
+ Length cannot be empty
+ Length must be a decimal data
+ Write data of the length of the string must be in multiples of four
+ Read failure
+ Inventory failure
+ Stop failure
+ Open failure
+ Set the frequency failure
+ Set the frequency success
+ Read the frequency failure
+
+ Set the PWM success
+ Set the PWM failure
+
+
+ Read the PWM failure
+ Read the frequency success
+ Set the power failure
+ Set the power success
+ Read the power failure
+ Read the power success
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/rfid.xml b/app/src/main/res/values/rfid.xml
new file mode 100644
index 0000000..25a23b2
--- /dev/null
+++ b/app/src/main/res/values/rfid.xml
@@ -0,0 +1,14 @@
+
+
+
+ S50
+ S70
+
+
+
+ A
+ B
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..956a30f
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,1431 @@
+
+
+
+ demo_uhf
+ Settings
+ About
+ Display Settings
+ Input Domain/IP
+ PING Count
+ PING Success
+ PING failure
+ s
+ Background
+ Timeout(s)
+ Restart
+ Ping Result
+ Upload Result
+ Download Result
+ Start
+ Stop
+ Settings
+ Settings
+ Network unavailable
+ Network is connected
+ Network unavailable
+ Domain/IP Error
+ loading...
+ NO DATA
+ ERROR
+ CHANGED
+ Unmatched
+ AppCenter
+ Press again to exit the program
+ Upload Tool %s
+ Download Tool %s
+ Back
+ OK
+ Exit
+ Save
+ Cancel
+ Clear
+ Close
+ ..(up)
+ .(refresh)
+ File Path
+ Browse
+ No permission
+ Download Tool
+ Upload Tool
+ Ping
+ Download
+ Upload
+ Upload
+ Upgrade
+ PingActivity
+ Hello world!
+ Packet Size
+ Ping Tool %s
+ 1D Barcode Tool
+ 2D Barcode Tool
+ 1D
+ 2D
+ Scan
+ Clear
+ init Barcode
+ Interval
+ Work
+ Wait
+ Compare
+ Auto,interval
+ Scan failure
+
+ Scan canceled
+ Scan timeout
+
+ Barcode error
+ total
+ success
+ failure
+ error
+ error
+ success
+ failure
+ BT Printer
+
+ decode time
+
+
+ Send
+ Print
+ Clear
+ Please connect the bluetooth printer
+ Please select a device!!
+ Connecting...
+ Connected:
+ Not connected
+ 4
+ Grayscale
+ (1~8)
+ HELLO WORLD! \n
+
+
+ Scanning...
+ Select a device
+ No Matching
+ Not found
+ Matched
+ Other Devices
+ Scan
+ UHF
+
+
+ Inventory Tag
+ Total
+ Single
+ Auto
+ Anti
+ Q value:
+ Start
+ Stop
+ EPC
+ Length
+ Count
+ Clear
+ Import
+ Tag
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+
+
+ ID Card
+ Animal Tag
+ HiTag
+ HDX Tag
+ EM4450
+ HID PROXIMITY
+
+
+
+ Barcode
+ RFID
+ UHF
+ Fingerprint
+
+
+
+ None
+ Odd
+ Even
+
+
+
+ Read EPC
+ Use EPC
+ EPC:
+ Bank:
+ Ptr:
+ Len:
+ Access Pwd:
+ Lock Code:
+ Read Mode:
+ Auto
+ Anti
+ 2级参数设置
+ Block:
+ Ptr:
+ Len:
+ Data:
+ Read
+
+ Kill:
+ Access:
+ UII:
+ TID:
+ USER:
+
+ Read
+ Write
+
+ filter
+
+
+ Temporary mask
+ Permanent mask
+ Open
+ Lock
+ Session ID
+ Inventoried Flag
+ Get Session
+ Set Session
+
+ RESERVED
+ EPC
+ TID
+ USER
+
+
+ EPC
+ TID
+ USER
+
+
+ Single
+ Auto
+ Anti(1 level)
+ Anti(2 level)
+
+
+ S0
+ S1
+ S2
+ S3
+
+
+ A
+ B
+
+
+ Output Power:
+ Set Power
+ Set Pwm
+ Get Pwm
+ Get Power
+ dBm
+
+
+ RFLink:
+ Set Link
+ Get Link
+
+
+
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+
+
+
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+
+
+
+
+ 请选择UII的去向
+ Read Data
+ Write Data
+ Erase Data
+ Lock Data
+ Confirm
+ Cancel
+
+
+ Tags List
+ Read UII
+
+
+ Stop
+ Back
+
+
+ EPC:
+ Block:
+ Ptr:
+ Len:
+ Count:
+ Data:
+ Status:
+
+
+ EPC:
+ Write Mode:
+ Write Data:
+ Write Data
+
+
+ Singleword
+ Multiword
+
+
+
+ EPC:
+ Kill Pwd:
+ Access Pwd:
+ UII:
+ TID:
+ USER:
+ Lock Code:
+ Create Code
+ Lock
+
+
+ Hold
+ Lock
+ Unlock
+ Permanent Lock
+ Permanent Unlock
+
+
+
+ EPC:
+ Kill Pwd:
+ Kill
+
+
+ Block:
+ Ptr:
+ Mask:
+ S/N:
+ Count:
+ Add
+ Del
+ Select
+ Read
+
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+
+
+
+
+ R2000 Function
+
+ Protocol(Only R2000):
+ Find hidden area(QT Tag):
+ EPC And TID Mode:
+
+ FastID Mode:
+ TagFocus Mode:
+
+ QT Tag
+ Working Mode:
+ Hop:
+
+ Set Frequency
+
+ Set FreHop
+
+ Set QTPara
+ Get QTPara
+
+
+ Set Protocol
+ Frequency Range:
+ Get Frequency
+ The starting frequency integer:
+ 840
+ +
+ -
+ Starting frequency of the decimal:
+ 50
+ +
+ -
+ band base number:
+ Channel:
+ Channel number not less than 1
+ Channel Bandwidth:
+ Freq Jump:
+ Calculation
+ MHz
+ KHz
+
+
+ China Standard(920~925MHz)
+ China Standard(840~845MHz)
+ ETSI Standard(865~868MHz)
+ Fixed Frequency(915MHz)
+ United States Standard(902~928MHz)
+
+
+
+
+ 865.700
+ 866.300
+ 866.900
+ 867.500
+ 920.625
+ 920.875
+ 921.125
+ 921.375
+ 921.625
+ 921.875
+ 922.125
+ 922.375
+ 922.625
+ 922.875
+ 923.125
+ 923.375
+ 923.625
+ 923.875
+ 924.125
+ 924.375
+
+
+
+
+ 902.75
+ 903.25
+ 903.75
+ 904.25
+ 904.75
+ 905.25
+ 905.75
+ 906.25
+ 906.75
+ 907.25
+ 907.75
+ 908.25
+ 908.75
+ 909.25
+ 909.75
+ 910.25
+ 910.75
+ 911.25
+ 911.75
+ 912.25
+ 912.75
+ 913.25
+ 913.75
+ 914.25
+ 914.75
+ 915.25
+ 915.75
+ 916.25
+ 916.75
+ 917.25
+ 917.75
+ 918.25
+ 918.75
+ 919.25
+ 919.75
+ 920.25
+ 920.75
+ 921.25
+ 921.75
+ 922.25
+ 922.75
+ 923.25
+ 923.75
+ 924.25
+ 924.75
+ 925.25
+ 925.75
+ 926.25
+ 926.75
+ 927.25
+
+
+
+
+
+ ISO 18000-6C
+ ISO 18000-6D
+
+
+
+ DSB_ASK/FM0/40KHz
+ PR_ASK/Miller4/250KHz
+ PR_ASK/Miller4/300KHz
+ DSB_ASK/FM0/400KHz
+
+
+
+
+ level1(22)
+ level2(36)
+ level3(50)
+ level4(60)
+ level5(70)
+
+
+
+
+ 32bytes
+ 64bytes
+ 128bytes
+ 256bytes
+
+
+
+
+ 0
+ 1
+
+
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+
+
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+
+
+ 随机跳频
+ 从高往低顺序跳频
+ 从低往高顺序跳频
+
+
+ 5V
+ 3V
+ 1.8V
+ iso
+
+
+ 9600
+ 19200
+ 38400
+ 43000
+ 56000
+ 57600
+ 115200
+
+
+
+ 9600
+ 19200
+ 38400
+ 57600
+ 115200
+
+
+
+ 600
+ 1200
+ 2400
+ 4800
+ 9600
+ 19200
+ 38400
+ 57600
+ 115200
+
+
+
+
+
+ 57600
+ 115200
+
+
+
+
+
+
+ AES
+ DES
+
+
+
+
+ 00
+ 01
+ 02
+ 03
+ 04
+ 05
+ 06
+ 07
+ 08
+ 09
+ 0A
+ 0B
+ 0C
+ 0D
+
+
+ UHF Settings
+ Network
+ Channel
+ Level
+ SSID
+ Status
+ TestActivity
+ Connected To:
+ Pause
+ Continue
+ WiFi Count:
+ Connected To
+ BSSID:
+ Security:
+ Pwd:
+ IP:
+ SP:
+ Status:
+ Network Type:
+ SS:
+ GPS
+ Lon:
+ Lat:
+ Satellite:
+ Altitude:
+ Status:
+ Time:
+ Settings
+ 14443A
+ 15693
+ Tag Type:
+
+ General
+ Automatic
+
+
+ Key Type:
+ Key:
+ Sector:
+ Block:
+ Read
+ Write
+ UID:
+ Scan
+ AFI(1 Byte)
+ DSFID(1 Byte)
+ Read ID
+ Write
+ Lock
+ Write
+ Lock
+ Auto R/W
+ Read
+ Write
+ R/W
+ Total:
+ success(R):
+ failure(R):
+ success(W):
+ failure(W):
+ RFID Version
+
+ PSAM Version
+
+
+ RFID Upgrade
+
+ PSAM Upgrade
+
+
+ UHF Version
+ Fingerprint Version
+ RAM:
+ Storage:
+ Display:
+ CPU:
+ Model:
+ Android version:
+ Build number:
+ Kernel version:
+ jar Version:
+ MAC:
+ SN:
+ IMEI:
+ Please select a function ...
+ Keyboard
+ P\no\nw\ne\nr
+ HOME
+ BACK
+ Ping...
+ Domain/IP Error
+ Network is not connected
+ Please select a file first
+ The file is not exist
+ File Size:
+ Start Time:
+ End Time:
+ Used Time:
+ Speed(avg):
+ Download File
+ Confirm to download the file?
+ Confirm
+ Cancel
+ Close
+ The file is not exist
+ Download Complete
+ Download failed
+ Upload Complete
+ Upload failed
+ Test Results
+ Completed Size:
+ Used Time:
+ Sd card does not exist
+ Downloading ...
+ Uploading ...
+ Upload was cancelled
+ Download was cancelled
+ Bluetooth devices do not support
+ Mobile
+ No Sim
+ Emergency calls only
+ In Service
+ Out of Service
+ Power off
+ Connection fail
+ Connecting...
+ WiFi Unavailable
+ Connect
+ Speed:
+ Level:
+ Please open the GPS navigation...
+ GPS positioning success
+ Locating...
+ Finish positioning
+ The satellite signal
+ Scan
+ Read
+ Write
+ Config
+ Kill
+ Lock
+ Scan failed
+ Auto Scan
+ Ping
+ ping...,After the completion of the click to view
+ Finish
+ File
+ Battery
+
+ Reboot Test
+
+
+ Tips:Results are stored in the SD card in the handset/BatteryMonitor directory.
+ Battery Monitor
+ Monitoring
+
+ Default
+ Custom
+
+
+ NOT CHARGING
+ CHARGING
+ DISCHARGING
+ CHARGING
+ FULL
+ UNKNOWN
+ UNKNOWN
+ GOOD
+ DEAD
+ OVER VOLTAGE
+ OVERHEAT
+ main level:
+ voltage:
+ temperature:
+ extra level:
+
+ extra current:
+
+ Fingerprint
+ Identification
+ acquisition
+ Page ID
+ Mode
+ Default
+ ISO
+ Name
+ Message
+ Do you want to empty the Data?
+ Confirm
+ Cancel
+ Acquisition
+ Stop
+ Identification
+ Page ID cannot be empty
+ Name cannot be empty
+ Page ID must be a number
+ Page ID must be in the range of 0 ~ 254
+ Acquisition success
+ Acquisition failure
+ Image
+ Image(ISO)
+ Auto
+ Failed to get the fingerprint images
+ Device initialization failed
+
+
+ RFID upgrade failed
+ RFID upgrade success
+
+
+ PSAM upgrade failed
+ PSAM upgrade success
+
+ Identification failure
+ Identification success
+ Score
+ Data
+ Config
+ Import
+ Reset
+ Import failure(success:%1$d,failure:%2$d)
+ Import success
+ Are you sure to reset?
+ Reset failure
+ Reset success
+ index
+ Page ID
+ Name
+ Time
+ Total(local):
+ Total(model):
+ Delete
+ Clear
+
+ Threshold
+ Packet size
+
+ Password
+
+ Set Password
+ verify password
+
+
+ Set Threshold
+ Get Threshold
+
+
+ Set Baudrate
+ Get Baudrate
+
+
+ Re-Initialize
+
+ Set Packet Size
+ Get Packet Size
+
+
+ Set the threshold success
+ Set the threshold failure
+
+ Set the Baudrate success
+ Set the Baudrate failure
+
+
+ Set the packet size success
+ Set the packet size failure
+
+ Set the password success
+ Set the password failure
+
+ Verify the password success
+ Verify the password failure
+
+ No operator information
+ RFID_LF
+ RFID_Needle
+ Choose file
+ Are you sure select the file?
+ Confirm
+ Cancel
+ Cancel
+ Input cannot be empty
+ Message
+ GPS is not open, whether to open?
+ YES
+ NO
+ Message
+ No paired bluetooth devices, please go to the matches
+ YES
+ NO
+ Connection failed, please check whether the device is being used
+ Tag Type:
+ Scan failure
+ Page ID:
+ Data:
+ Write
+ Read
+ The data can not be empty
+ Please enter the HEX 4 bytes
+ Data is written to success
+ Data is written to failure
+ Can only be 0,3,5~13, one of the page write data
+ Volume
+ VOICE CALL
+ SYSTEM
+ RING
+ MUSIC
+ NOTIFICATION
+ ALARM
+ init...
+
+ Upgrading...\nDo not exit, lest damage hardware
+
+
+ Sensor
+ Open
+ Auto
+ Stop
+ Close
+ R
+ G
+ B
+ Light
+ Sensor
+ Brightness
+
+ Compass
+ Gyroscope
+
+ P-Sensor value:
+ Light Sensor value:
+ Open led light
+ Close led light
+ Open the led light failure
+ Close the led light failure
+ Please select a function module
+ PingPopActivity
+ Beidou
+ Success
+ Locating...
+ Finish positioning
+ The satellite signal
+ Lon:
+ Lat:
+ Satellite:
+ Altitude:
+ Status:
+ Time:
+ GPS
+ BD
+ GPS & BD
+ COLD
+ WARM
+ HOT
+ 14443A CPU
+ Command
+ Data
+ Initialize
+ Send
+ Get UID
+ Auto
+ Stop
+ RATS and PPS error
+ CPU ID
+ RATS data
+ Send failed
+ Get UID failed
+ UID:
+ Failed to get the card number
+ 14443B
+ Initialization failed
+ Initialize the data returned
+ Command returns data
+ ToServicePageActivity
+ Unable to download the installation file, please check the SD card is mounted
+ Please wait...
+ Message
+ You currently have is the latest version
+ Unable to get updated version information
+ confirm
+ cancel
+ Software version update
+ Now
+ Last
+ Downloading
+ PSAM
+ Voltage
+ Parameter
+ Baud
+ CMD
+ DATA
+ Send
+ Set
+ Clear
+
+ Save Records
+
+ stored in the handset/PSAM directory.
+ Card 1
+ Card 2
+
+ failed
+ Analog Call
+ Press the recording
+ Loosen the play
+ Camera
+ Device has only one camera!
+ Switch Camera
+ No camera equipment!
+
+
+ Camera barcode
+ Applications
+ Bookmarks
+ Add to calendar
+ Add contact
+ Back
+ Book Search
+ Cancel
+ Custom search
+ Dial number
+ Done
+ Send email
+ Get directions
+ Shopper
+ Send MMS
+ OK
+ Open browser
+ Product Search
+ Search contents
+ Application
+ Bookmark
+ Share via email
+ Share via SMS
+ Clipboard
+ Contact
+ Show map
+ Send SMS
+ Web search
+ Connect to Network
+ Contact info
+ Email address
+ Geographic coordinates
+ Phone number
+ SMS address
+ Plain text
+ Clear history
+ Clear
+ Barcode Scanner history
+ Empty
+ No barcode scans have been recorded
+ Send history
+ History
+ Use MECARD
+ Use vCard
+ Help
+ History
+ Settings
+ Share
+ Bulk mode: barcode scanned and saved
+ Sorry, the Android camera encountered a problem. You may need to restart the device.
+ Format
+ Metadata
+ Hi
+ Place a barcode inside the viewfinder rectangle to scan it.
+ Time
+ Type
+ Could not encode a barcode from the data provided.
+ Google Books
+ Google Product Search
+ Google Shopper is not installed
+ Google Shopper combines barcode scanning with online and local prices, reviews and more without opening the browser. Would you like to try it?
+ Sorry, the requested application could not be launched. The barcode contents may be invalid.
+ Redirect
+ Sorry, this book is not searchable.
+ Sorry, the search encountered a problem.
+ No page returned
+ Page
+ Results
+ Searching book\u2026
+ Snippet not available
+ Unknown page
+ You can share data by displaying a barcode on your screen and scanning it with another phone.
+ Here are the contents of a barcode I scanned
+ Or type some text and press Enter
+ Are you sure?
+ Sorry, the SD card is not accessible.
+ When a barcode is found\u2026
+ Use auto focus
+ Scan and save many barcodes continuously
+ Bulk scan mode
+ Copy to clipboard
+ Substitutions: %s = contents, %f = format, %t = type
+ Custom search URL
+ 1D barcodes
+ Data Matrix
+ QR Codes
+ Device Bug Workarounds
+ Use only standard focus mode
+ No continuous focus
+ No exposure
+ Improves scanning in low light on some phones, but may cause glare. Does not work on all phones.
+ Use front light
+ General settings
+ Settings
+ Beep
+ Store multiple scans of the same barcode in History
+ Remember duplicates
+ Result settings
+ When scanning for barcodes, decode\u2026
+ Search country
+ Try Barcode Scanner+
+ Enhanced with new features and interface
+ Try to retrieve more information about the barcode contents
+ Retrieve more info
+ Vibrate
+ Found contact info
+ Found calendar event
+ Found email address
+ Found geographic coordinates
+ Found book
+ Found product
+ Found SMS address
+ Found phone number
+ Found plain text
+ Found URL
+ Found WLAN Configuration
+ Google Book Search
+ Share via barcode
+ Requesting connection to network\u2026
+ Network Name
+ Type
+
+
+
+ Network_Auto
+
+ Scan
+ Back
+ Password
+ 1~6 bytes hex
+ Password cannot be empty
+ Properties
+ Change Password
+ Version
+ New App
+ Format
+ Delete
+ New File
+
+ Select application failure
+ Please enter a hexadecimal number
+ Verification failed
+ Failed to get the application
+ Failed to get the file
+ Failed to get the infomation
+
+
+ Password attributes can be modified
+ Add or delete the application authentication codes
+ Operation application authentication codes
+ The password can be modified
+
+ failed
+ succeed
+
+ App ID
+ File count
+ comm setting
+ Create
+ Modify
+ App ID must be 3 bytes
+ The file count must be 1 byte
+ Communications Settings must be 1 byte
+ File No
+
+
+ 00
+ 01
+ 02
+ 03
+ 04
+ 05
+ 06
+ 07
+ 08
+ 09
+ 0A
+ 0B
+ 0C
+ 0D
+ 0E
+ 0F
+
+
+ size
+ Encryption
+
+ Transparent
+ 3DES
+
+
+
+ Read
+ Write
+ Read/Write
+ Update
+
+ file is full
+
+ File No cannot be empty
+ Data File
+ Value File
+
+ Min
+ Max
+ Now
+ Cannot be empty
+ Balance
+ Credit
+ Debit
+
+ Data
+ Card Properties
+ Card Version
+
+ Unknown file types
+
+ Modify App password
+ App properties
+ Tips
+ If confirm the operation?
+
+
+ 3 bytes hex number
+ Add or delete the file authentication codes
+ Operation file authentication codes
+
+ Change the app code required permissions
+ The largest number of key
+ Click to enter
+
+ Key broadcast
+ NFC
+ NFC is not available
+ Please open the NFC function
+ The mobile phone back to start writing NFC Tags
+ Reader
+ Writer
+ Cannot write to this tag. This tag is read-only.
+ The content is too long
+ Tag write success
+ Cannot write to this tag. This tag does not support NDEF.
+ Cannot write to this tag due to an Exception.
+ Printer
+ The printer is out of paper
+
+
+ MINI
+ FULL
+ 2D(S)
+
+
+ Hello blank fragment
+ Scan
+ Picture
+ Config
+
+ Get the image data failed
+ Saved pictures to album
+ ParamNum
+ ParamVal
+
+ Get
+ Set
+
+
+ Set successfully
+ Set failure
+ Settings
+ Bar code scan setup
+
+ RFID
+
+
+ PSAM
+
+
+ Enable release key off scan
+
+ Infrared
+
+ UART
+
+ Received data
+
+ Reboot count:
+ Complete:
+ Setting:
+ UART:
+
+ HEX
+
+ Open failed
+ Open succeed
+
+ Close failed
+ Close succeed
+
+ file not have the correct format
+ Check:
+
+ Get Power
+
+ elapsed time
+
+ 97
+ 07
+ meter number
+
+
+
+ Menu
+ Common settings
+ R2000 settings
+ Set link parameters
+ Get link parameters
+ Open the tagFocus
+ Open the FastID
+ Open the EPC and TID
+ Close the tagFocus
+ Close the FastID
+ Close the EPC and TID
+ Erase
+ Please enter the stored data
+ Set success
+ Set fail
+ Set QT parameters successfully
+ Failed to set QT parameters
+ Get QT parameters successfully
+ Failed to obtain QT parameters
+ Please open the QT tag first
+ Enable
+ Disable
+ Disable success
+ Disable fail
+ Data format is incorrect
+ Tag number format is incorrect
+ R2000 module only
+ Set the filter failure
+ Set the filter success
+ Set the protocol failure
+ Set the protocol success
+
+ Set the frequency Hopping success
+ Set the frequency Hopping failure
+
+ success
+ failure
+
+ success
+ failure
+
+ China
+ Europe
+ America
+ Others
+ Hop type:
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..101f864
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..99ae907
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,30 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ maven { url 'https://jitpack.io' }
+ google()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.6.2'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ mavenLocal()
+ maven { url 'https://dl.google.com/dl/android/maven2' }
+ maven { url 'https://jitpack.io' }
+ maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' }
+ google()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..199d16e
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,20 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
+
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..f6b961f
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..b888843
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Jul 29 10:58:59 CST 2020
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..8dca8e2
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,2 @@
+include ':app'
+//,':demo-uhf_example2'