Java tutorial
/* * Copyright (C) 2016 The Josh Tool Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mumu.pokemongogo; import android.app.Service; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; import android.os.Handler; import android.os.IBinder; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.support.v7.view.ContextThemeWrapper; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; import android.widget.TextView; import com.google.android.gms.maps.model.LatLng; import com.mumu.pokemongogo.headicon.HeadIconView; import com.mumu.pokemongogo.location.FakeLocation; import com.mumu.pokemongogo.location.FakeLocationManager; import com.mumu.pokemongogo.location.HumanWalkSimulator; import java.util.ArrayList; public class HeadService extends Service { private static final String TAG = "PokemonGoGo"; private final Handler mHandler = new Handler(); private FakeLocationManager mFakeLocationManager; public static final String ACTION_HANDLE_NAVIGATION = "ActionNavigation"; public static final String ACTION_HANDLE_TELEPORT = "ActionTeleport"; public static final String ACTION_HANDLE_INCUBATING = "ActionIncubating"; public static final String EXTRA_DATA = "DataLocation"; private Context mContext; // View objects private WindowManager mWindowManager; private ArrayList<HeadIconView> mHeadIconList; private ArrayList<HeadIconView> mDirectionIconList; private static final int IDX_HEAD_ICON = 0; private static final int IDX_MSG_TEXT = 1; private static final int IDX_START_ICON = 2; private static final int IDX_HOME_ICON = 3; private static final int IDX_INCUBATOR_ICON = 4; private static final int IDX_SPEED_ICON = 5; private static final int IDX_UP_BUTTON = 0; private static final int IDX_DOWN_BUTTON = 1; private static final int IDX_LEFT_BUTTON = 2; private static final int IDX_RIGHT_BUTTON = 3; // game control private String mMessageText = ""; private boolean mThreadStart = false; private boolean mFreeWalking = false; private boolean mAutoIncubating = false; private double mAutoIncubatingRadius = 50; // default 50 meters private FakeLocation mAutoIncubatingOrigin; private double mWalkSpeed = 1.0; private int mTouchHeadIconCount = 0; // map control private static LatLng mMapLocation; /* * Runnable threads */ private final Runnable updateRunnable = new Runnable() { public void run() { updateUI(); } }; private void updateUI() { ((TextView) mHeadIconList.get(IDX_MSG_TEXT).getView()).setText(mMessageText); } @Override public IBinder onBind(Intent intent) { // Not used return null; } @Override public void onCreate() { super.onCreate(); mContext = this; mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); // On screen view initializing, do not mess around here initGamePanelViews(); initGameControlButtons(); mThreadStart = true; new GetMessageThread().start(); // Config fake location manager mFakeLocationManager = new FakeLocationManager(mContext, null); // Set enable mFakeLocationManager.setEnable(true); } private void initGamePanelViews() { mHeadIconList = new ArrayList<>(); // Head Icon HeadIconView headIcon = new HeadIconView(new ImageView(this), mWindowManager, 0, 0); headIcon.getImageView().setImageResource(R.mipmap.ic_launcher); headIcon.setOnTapListener(new HeadIconView.OnTapListener() { @Override public void onTap(View view) { configHeadIconShowing(HeadIconView.AUTO); } @Override public void onLongPress(View view) { showExitConfirmDialog(); } }); mHeadIconList.add(headIcon); // Message Text Icon HeadIconView msgText = new HeadIconView(new TextView(this), mWindowManager, 120, 13); msgText.getTextView().setText(""); msgText.getTextView().setTextColor(Color.BLACK); msgText.getView().setBackgroundColor(Color.WHITE); mHeadIconList.add(msgText); // Start Game Pad Icon HeadIconView startIcon = new HeadIconView(new ImageView(this), mWindowManager, 0, 75); startIcon.getImageView().setImageResource(R.drawable.ic_play); startIcon.setOnTapListener(new HeadIconView.OnTapListener() { @Override public void onTap(View view) { configFreeWalking(); } @Override public void onLongPress(View view) { } }); mHeadIconList.add(startIcon); // Home Icon HeadIconView homeIcon = new HeadIconView(new ImageView(this), mWindowManager, 80, 90); homeIcon.getImageView().setImageResource(R.drawable.ic_location_pin); homeIcon.setOnTapListener(new HeadIconView.OnTapListener() { @Override public void onTap(View view) { Log.d(TAG, "config map icon"); mFakeLocationManager.cancelAutoPilot(); configHeadIconShowing(HeadIconView.INVISIBLE); Intent mapIntent = new Intent(mContext, MapLocationViewer.class); mapIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(mapIntent); } @Override public void onLongPress(View view) { } }); mHeadIconList.add(homeIcon); // Incubator Icon HeadIconView incubatorIcon = new HeadIconView(new ImageView(this), mWindowManager, 150, 90); incubatorIcon.getImageView().setImageResource(R.drawable.ic_egg_disabled); incubatorIcon.setOnTapListener(new HeadIconView.OnTapListener() { @Override public void onTap(View view) { Log.d(TAG, "config auto incubating"); configAutoIncubating(); } @Override public void onLongPress(View view) { } }); mHeadIconList.add(incubatorIcon); // Speed control Icon HeadIconView speedIcon = new HeadIconView(new ImageView(this), mWindowManager, 220, 85); speedIcon.getImageView().setImageResource(R.drawable.ic_one); speedIcon.setOnTapListener(new HeadIconView.OnTapListener() { @Override public void onTap(View view) { Log.d(TAG, "config speed"); if (!mAutoIncubating) configSpeed(); else mMessageText = "You can't"; } @Override public void onLongPress(View view) { } }); mHeadIconList.add(speedIcon); // Share the same on move listener for moving in the same time HeadIconView.OnMoveListener moveListener = new HeadIconView.OnMoveListener() { @Override public void onMove(int initialX, int initialY, float initialTouchX, float initialTouchY, MotionEvent event) { for (HeadIconView icon : mHeadIconList) { icon.moveIconDefault(initialX, initialY, initialTouchX, initialTouchY, event); } } }; // Set all to add for (HeadIconView icon : mHeadIconList) { icon.addView(); icon.setOnMoveListener(moveListener); } // Set default visibility mHeadIconList.get(IDX_START_ICON).setVisibility(View.INVISIBLE); mHeadIconList.get(IDX_HOME_ICON).setVisibility(View.INVISIBLE); mHeadIconList.get(IDX_INCUBATOR_ICON).setVisibility(View.INVISIBLE); mHeadIconList.get(IDX_SPEED_ICON).setVisibility(View.INVISIBLE); } private void initGameControlButtons() { mDirectionIconList = new ArrayList<>(); // Up button HeadIconView upButton = new HeadIconView(new ImageView(this), mWindowManager, 130, 160); upButton.getImageView().setImageResource(R.drawable.ic_arrow_up); upButton.getImageView() .setBackgroundColor(ContextCompat.getColor(mContext, R.color.button_half_transparent)); upButton.setOnTapListener(new HeadIconView.OnTapListener() { @Override public void onTap(View view) { mFakeLocationManager.setSpeed(mWalkSpeed); mFakeLocationManager.walkPace(FakeLocation.NORTH, 1.0); } @Override public void onLongPress(View view) { } }); mDirectionIconList.add(upButton); // Down button HeadIconView downButton = new HeadIconView(new ImageView(this), mWindowManager, 130, 0); downButton.getImageView().setImageResource(R.drawable.ic_arrow_down); downButton.getImageView() .setBackgroundColor(ContextCompat.getColor(mContext, R.color.button_half_transparent)); downButton.setOnTapListener(new HeadIconView.OnTapListener() { @Override public void onTap(View view) { mFakeLocationManager.setSpeed(mWalkSpeed); mFakeLocationManager.walkPace(FakeLocation.SOUTH, 1.0); } @Override public void onLongPress(View view) { } }); mDirectionIconList.add(downButton); // Left button HeadIconView leftButton = new HeadIconView(new ImageView(this), mWindowManager, 50, 80); leftButton.getImageView().setImageResource(R.drawable.ic_arrow_left); leftButton.getImageView() .setBackgroundColor(ContextCompat.getColor(mContext, R.color.button_half_transparent)); leftButton.setOnTapListener(new HeadIconView.OnTapListener() { @Override public void onTap(View view) { mFakeLocationManager.setSpeed(mWalkSpeed); mFakeLocationManager.walkPace(FakeLocation.WEST, 1.0); } @Override public void onLongPress(View view) { } }); mDirectionIconList.add(leftButton); // Right button HeadIconView rightButton = new HeadIconView(new ImageView(this), mWindowManager, 210, 80); rightButton.getImageView().setImageResource(R.drawable.ic_arrow_right); rightButton.getImageView() .setBackgroundColor(ContextCompat.getColor(mContext, R.color.button_half_transparent)); rightButton.setOnTapListener(new HeadIconView.OnTapListener() { @Override public void onTap(View view) { mFakeLocationManager.setSpeed(mWalkSpeed); mFakeLocationManager.walkPace(FakeLocation.EAST, 1.0); } @Override public void onLongPress(View view) { } }); mDirectionIconList.add(rightButton); // North West button HeadIconView upLeftButton = new HeadIconView(new ImageView(this), mWindowManager, 50, 160); upLeftButton.getImageView().setImageResource(R.drawable.ic_arrow_squart); upLeftButton.getImageView() .setBackgroundColor(ContextCompat.getColor(mContext, R.color.button_half_transparent)); upLeftButton.setOnTapListener(new HeadIconView.OnTapListener() { @Override public void onTap(View view) { mFakeLocationManager.setSpeed(mWalkSpeed); mFakeLocationManager.walkPace(FakeLocation.NORTHWEST, 1.0); } @Override public void onLongPress(View view) { } }); mDirectionIconList.add(upLeftButton); // West South button HeadIconView leftDownButton = new HeadIconView(new ImageView(this), mWindowManager, 50, 0); leftDownButton.getImageView().setImageResource(R.drawable.ic_arrow_squart); leftDownButton.getImageView() .setBackgroundColor(ContextCompat.getColor(mContext, R.color.button_half_transparent)); leftDownButton.setOnTapListener(new HeadIconView.OnTapListener() { @Override public void onTap(View view) { mFakeLocationManager.setSpeed(mWalkSpeed); mFakeLocationManager.walkPace(FakeLocation.WESTSOUTH, 1.0); } @Override public void onLongPress(View view) { } }); mDirectionIconList.add(leftDownButton); // South East button HeadIconView downRightButton = new HeadIconView(new ImageView(this), mWindowManager, 210, 0); downRightButton.getImageView().setImageResource(R.drawable.ic_arrow_squart); downRightButton.getImageView() .setBackgroundColor(ContextCompat.getColor(mContext, R.color.button_half_transparent)); downRightButton.setOnTapListener(new HeadIconView.OnTapListener() { @Override public void onTap(View view) { mFakeLocationManager.setSpeed(mWalkSpeed); mFakeLocationManager.walkPace(FakeLocation.SOUTHEAST, 1.0); } @Override public void onLongPress(View view) { } }); mDirectionIconList.add(downRightButton); // East North button HeadIconView rightUpButton = new HeadIconView(new ImageView(this), mWindowManager, 210, 160); rightUpButton.getImageView().setImageResource(R.drawable.ic_arrow_squart); rightUpButton.getImageView() .setBackgroundColor(ContextCompat.getColor(mContext, R.color.button_half_transparent)); rightUpButton.setOnTapListener(new HeadIconView.OnTapListener() { @Override public void onTap(View view) { mFakeLocationManager.setSpeed(mWalkSpeed); mFakeLocationManager.walkPace(FakeLocation.EASTNORTH, 1.0); } @Override public void onLongPress(View view) { } }); mDirectionIconList.add(rightUpButton); // add view and set invisible for (HeadIconView icon : mDirectionIconList) { icon.setVisibility(View.INVISIBLE); icon.setGravity(Gravity.BOTTOM | Gravity.START, false); icon.addView(); } } private void StopService() { stopSelf(); } @Override public void onDestroy() { super.onDestroy(); mThreadStart = false; // Game tool for (HeadIconView icon : mHeadIconList) { icon.removeView(); } // Game control tool for (HeadIconView icon : mDirectionIconList) { icon.removeView(); } if (mFakeLocationManager != null) mFakeLocationManager.setEnable(false); } @Override public int onStartCommand(Intent intent, int flags, int startId) { LatLng mapLocation; double mapRadius; if (intent != null) { final String action = intent.getAction(); if (action != null) { configHeadIconShowing(HeadIconView.VISIBLE); switch (action) { case ACTION_HANDLE_NAVIGATION: mapLocation = intent.getParcelableExtra(EXTRA_DATA); Log.d(TAG, "Service receive LAT = " + mapLocation.latitude + " and LONG = " + mapLocation.longitude); mMapLocation = mapLocation; mMessageText = mContext.getString(R.string.msg_map_navigating); doMapNavigation(); break; case ACTION_HANDLE_TELEPORT: mapLocation = intent.getParcelableExtra(EXTRA_DATA); Log.d(TAG, "Service receive LAT = " + mapLocation.latitude + " and LONG = " + mapLocation.longitude); mMapLocation = mapLocation; mMessageText = mContext.getString(R.string.msg_map_teleporting); doMapTeleporting(); break; case ACTION_HANDLE_INCUBATING: mapRadius = intent.getDoubleExtra(EXTRA_DATA, 50.0); Log.d(TAG, "Service receive Radius = " + mapRadius); mAutoIncubatingRadius = mapRadius; mMessageText = mContext.getString(R.string.msg_start_incubating); mHeadIconList.get(IDX_INCUBATOR_ICON).getImageView() .setImageResource(R.drawable.ic_egg_enabled); mHeadIconList.get(IDX_SPEED_ICON).getImageView().setImageResource(R.drawable.ic_slow); mAutoIncubating = true; startAutoIncubating(); break; } } } return START_NOT_STICKY; } public int getCurrentHeadIconVisibility() { if (mTouchHeadIconCount % 2 == 0) return HeadIconView.INVISIBLE; else return HeadIconView.VISIBLE; } private void configHeadIconShowing(int visible) { // If current status is what we want, return here if (getCurrentHeadIconVisibility() == visible) return; // Increase icon touch count mTouchHeadIconCount++; mHeadIconList.get(IDX_START_ICON).setVisibility(getCurrentHeadIconVisibility()); mHeadIconList.get(IDX_HOME_ICON).setVisibility(getCurrentHeadIconVisibility()); mHeadIconList.get(IDX_INCUBATOR_ICON).setVisibility(getCurrentHeadIconVisibility()); mHeadIconList.get(IDX_SPEED_ICON).setVisibility(getCurrentHeadIconVisibility()); } private void showExitConfirmDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(mContext, R.style.myDialog)) .setTitle(getString(R.string.headservice_stop_title)) .setMessage(getString(R.string.headservice_stop_info)).setPositiveButton( getString(R.string.headservice_stop_button), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // Let's do some background stuff StopService(); } }) .setNegativeButton(getString(R.string.startup_cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); AlertDialog alert = builder.create(); alert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); alert.show(); } private void configFreeWalking() { mFreeWalking = !mFreeWalking; mHeadIconList.get(IDX_START_ICON).getImageView() .setImageResource(mFreeWalking ? R.drawable.ic_pause : R.drawable.ic_play); for (HeadIconView icon : mDirectionIconList) { icon.setVisibility(mFreeWalking ? View.VISIBLE : View.INVISIBLE); } } private void configAutoIncubating() { if (mAutoIncubating) { Log.d(TAG, "Stop auto incubating"); mMessageText = mContext.getString(R.string.msg_stop_incubating); mHeadIconList.get(IDX_INCUBATOR_ICON).getImageView().setImageResource(R.drawable.ic_egg_disabled); mAutoIncubating = false; } else { Log.d(TAG, "Start auto incubating"); mFakeLocationManager.cancelAutoPilot(); configHeadIconShowing(HeadIconView.INVISIBLE); Intent mapIntent = new Intent(mContext, MapAutoIncubating.class); mapIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(mapIntent); } } private void configSpeed() { ImageView iv = mHeadIconList.get(IDX_SPEED_ICON).getImageView(); if (mWalkSpeed == 1.0) { mWalkSpeed = 2.0; iv.setImageResource(R.drawable.ic_two); } else if (mWalkSpeed == 2.0) { mWalkSpeed = 4.0; iv.setImageResource(R.drawable.ic_three); } else if (mWalkSpeed == 4.0) { mWalkSpeed = 8.0; iv.setImageResource(R.drawable.ic_four); } else if (mWalkSpeed == 8.0) { mWalkSpeed = 32.0; iv.setImageResource(R.drawable.ic_five); } else if (mWalkSpeed == 32.0) { mWalkSpeed = 128.0; iv.setImageResource(R.drawable.ic_six); } else if (mWalkSpeed == 128.0) { mWalkSpeed = 0.7; iv.setImageResource(R.drawable.ic_slow); } else if (mWalkSpeed == 0.7) { mWalkSpeed = 1.0; iv.setImageResource(R.drawable.ic_one); } mFakeLocationManager.setSpeed(mWalkSpeed); } private void doMapNavigation() { if (mAutoIncubating) { mMessageText = mContext.getString(R.string.msg_stop_incubating_forcely); configAutoIncubating(); } mFakeLocationManager .setOnNavigationCompleteListener(new FakeLocationManager.OnNavigationCompleteListener() { @Override public void onNavigationComplete() { mMessageText = mContext.getString(R.string.msg_map_navi_done); } }); mFakeLocationManager.autoPilotTo(mMapLocation.latitude, mMapLocation.longitude, true); } private void doMapTeleporting() { if (mAutoIncubating) { mMessageText = mContext.getString(R.string.msg_stop_incubating_forcely); configAutoIncubating(); } FakeLocation loc = new FakeLocation(mMapLocation.latitude, mMapLocation.longitude, 13.3122, 7.91231); mFakeLocationManager.setLocation(loc); } class GetMessageThread extends Thread { public void run() { while (mThreadStart) { mHandler.post(updateRunnable); try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } } } } void startAutoIncubating() { mAutoIncubatingOrigin = mFakeLocationManager.getCurrentLocation(); new StartAutoIncubatingThread().start(); } class StartAutoIncubatingThread extends Thread { public void run() { HumanWalkSimulator walkSimulator = new HumanWalkSimulator(); int previousDirection = -1; int directionCheck; int directionKeep = 0; while (mAutoIncubating) { int nextDirection = walkSimulator.getNextDirection(); double speedChange = Math.sqrt(Math.random() + 1.0); // limit speed to 1 to 1.5 double directionRatio = 1.0 - Math.random() / 4.0; // the ratio of the direction, limit to 0.75 ~ 1 // check if out of bound if (directionKeep > 0) { directionKeep--; nextDirection = previousDirection; } else { directionCheck = mFakeLocationManager.getNewDirectionInBound(mAutoIncubatingOrigin, mAutoIncubatingRadius, nextDirection); if (directionCheck != nextDirection) { Log.w(TAG, "Out of bound detected, ignoring walk simulator"); nextDirection = directionCheck; directionKeep = 6; } } mFakeLocationManager.walkPace(nextDirection, directionRatio); mFakeLocationManager.setSpeed(speedChange); if (previousDirection != nextDirection) { Log.d(TAG, "Direction has changed from " + previousDirection + " to " + nextDirection); previousDirection = nextDirection; } try { Thread.sleep((int) (Math.random() * 1000) + 500); } catch (Exception e) { e.printStackTrace(); } } } } }