In app based on Vuforia I want to have some demo also based on Vuforia . So I stop one Vuforia (ARactivity) and use intent to start new activity (Md2activity.class) with something like this:
arActivity.stopAR();
Intent intent = new Intent(arActivity, Md2activity.class);
arActivity.startActivity(intent);
and .stopAR method:
public void stopAR(){
try {
vuforiaAppSession.stopAR();
} catch (SampleApplicationException e) {
e.printStackTrace();
}
vuforiaAppSession.stopCamera();
mTextures.clear();
mTextures = null;
}
I can see in consol that it's working fine. Camera recognizes targets etc. But I don't have camera view on the screen. Just ProgressBar.
edit:
public class Md2activity extends Activity implements SampleApplicationControl,
SampleAppMenuInterface
{
private static final String LOGTAG = "Md2activity";
SampleApplicationSession vuforiaAppSession;
private DataSet mCurrentDataset;
private int mCurrentDatasetSelectionIndex = 0;
private int mStartDatasetsIndex = 0;
private int mDatasetsNumber = 0;
private ArrayList<String> mDatasetStrings = new ArrayList<String>();
private Activity mActivity;
private SampleApplicationControl mSessionControl;
// Our OpenGL view:
private SampleApplicationGLView mGlView;
// Our renderer:
private ImageTargetRendererMd2 mRenderer;
private GestureDetector mGestureDetector;
// The textures we will use for rendering:
private Vector<Texture> mTextures;
private boolean mSwitchDatasetAsap = false;
private boolean mFlash = false;
private boolean mContAutofocus = false;
private boolean mExtendedTracking = false;
private View mFlashOptionView;
private RelativeLayout mUILayout;
private SampleAppMenu mSampleAppMenu;
LoadingDialogHandler loadingDialogHandler = new LoadingDialogHandler(this);
// Alert Dialog used to display SDK errors
private AlertDialog mErrorDialog;
private boolean mIsDroidDevice = false;
// Called when the activity first starts or the user navigates back to an
// activity.
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(LOGTAG, "onCreate");
super.onCreate(savedInstanceState);
//setContentView(R.layout.camera_md2);
vuforiaAppSession = new SampleApplicationSession(this);
startLoadingAnimation();
mDatasetStrings.add("StonesAndChips.xml");
mDatasetStrings.add("Tarmac.xml");
vuforiaAppSession
.initAR(this, ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
mGestureDetector = new GestureDetector(this, new dr.ar.browser.Md2activity.GestureListener());
// Load any sample specific textures:
mTextures = new Vector<Texture>();
mIsDroidDevice = android.os.Build.MODEL.toLowerCase().startsWith(
"droid");
}
// Process Single Tap event to trigger autofocus
private class GestureListener extends
GestureDetector.SimpleOnGestureListener
{
// Used to set autofocus one second after a manual focus is triggered
private final Handler autofocusHandler = new Handler();
#Override
public boolean onDown(MotionEvent e)
{
return true;
}
#Override
public boolean onSingleTapUp(MotionEvent e)
{
// Generates a Handler to trigger autofocus
// after 1 second
autofocusHandler.postDelayed(new Runnable()
{
public void run()
{
boolean result = CameraDevice.getInstance().setFocusMode(
CameraDevice.FOCUS_MODE.FOCUS_MODE_TRIGGERAUTO);
if (!result)
Log.e("SingleTapUp", "Unable to trigger focus");
}
}, 1000L);
return true;
}
}
// Called when the activity will start interacting with the user.
#Override
protected void onResume()
{
Log.d(LOGTAG, "onResume");
super.onResume();
// This is needed for some Droid devices to force portrait
if (mIsDroidDevice)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
try
{
vuforiaAppSession.resumeAR();
} catch (SampleApplicationException e)
{
Log.e(LOGTAG, e.getString());
}
// Resume the GL view:
if (mGlView != null)
{
mGlView.setVisibility(View.VISIBLE);
mGlView.onResume();
}
}
// Callback for configuration changes the activity handles itself
#Override
public void onConfigurationChanged(Configuration config)
{
Log.d(LOGTAG, "onConfigurationChanged");
super.onConfigurationChanged(config);
vuforiaAppSession.onConfigurationChanged();
}
// Called when the system is about to start resuming a previous activity.
#Override
protected void onPause()
{
Log.d(LOGTAG, "onPause");
super.onPause();
if (mGlView != null)
{
mGlView.setVisibility(View.INVISIBLE);
mGlView.onPause();
}
// Turn off the flash
if (mFlashOptionView != null && mFlash)
{
// OnCheckedChangeListener is called upon changing the checked state
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
{
((Switch) mFlashOptionView).setChecked(false);
} else
{
((CheckBox) mFlashOptionView).setChecked(false);
}
}
try
{
vuforiaAppSession.pauseAR();
} catch (SampleApplicationException e)
{
Log.e(LOGTAG, e.getString());
}
}
// The final call you receive before your activity is destroyed.
#Override
protected void onDestroy()
{
Log.d(LOGTAG, "onDestroy");
super.onDestroy();
try
{
vuforiaAppSession.stopAR();
} catch (SampleApplicationException e)
{
Log.e(LOGTAG, e.getString());
}
// Unload texture:
mTextures.clear();
mTextures = null;
System.gc();
}
// Initializes AR application components.
private void initApplicationAR()
{
// Create OpenGL ES view:
int depthSize = 16;
int stencilSize = 0;
boolean translucent = Vuforia.requiresAlpha();
mGlView = new SampleApplicationGLView(this);
mGlView.init(translucent, depthSize, stencilSize);
mRenderer = new ImageTargetRendererMd2(this, vuforiaAppSession);
mGlView.setRenderer(mRenderer);
}
private void startLoadingAnimation()
{
mUILayout = (RelativeLayout) View.inflate(this, R.layout.camera_overlay,
null);
mUILayout.setVisibility(View.VISIBLE);
mUILayout.setBackgroundColor(Color.BLACK);
// Gets a reference to the loading dialog
loadingDialogHandler.mLoadingDialogContainer = mUILayout
.findViewById(R.id.loading_indicator);
// Shows the loading indicator at start
loadingDialogHandler
.sendEmptyMessage(LoadingDialogHandler.SHOW_LOADING_DIALOG);
// Adds the inflated layout to the view
addContentView(mUILayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
}
// Methods to load and destroy tracking data.
#Override
public boolean doLoadTrackersData()
{
TrackerManager tManager = TrackerManager.getInstance();
ObjectTracker objectTracker = (ObjectTracker) tManager
.getTracker(ObjectTracker.getClassType());
if (objectTracker == null)
return false;
if (mCurrentDataset == null)
mCurrentDataset = objectTracker.createDataSet();
if (mCurrentDataset == null)
return false;
if (!mCurrentDataset.load(
mDatasetStrings.get(mCurrentDatasetSelectionIndex),
STORAGE_TYPE.STORAGE_APPRESOURCE))
return false;
if (!objectTracker.activateDataSet(mCurrentDataset))
return false;
int numTrackables = mCurrentDataset.getNumTrackables();
for (int count = 0; count < numTrackables; count++)
{
Trackable trackable = mCurrentDataset.getTrackable(count);
if(isExtendedTrackingActive())
{
trackable.startExtendedTracking();
}
String name = "Current Dataset : " + trackable.getName();
trackable.setUserData(name);
Log.d(LOGTAG, "UserData:Set the following user data "
+ (String) trackable.getUserData());
}
return true;
}
#Override
public boolean doUnloadTrackersData()
{
// Indicate if the trackers were unloaded correctly
boolean result = true;
TrackerManager tManager = TrackerManager.getInstance();
ObjectTracker objectTracker = (ObjectTracker) tManager
.getTracker(ObjectTracker.getClassType());
if (objectTracker == null)
return false;
if (mCurrentDataset != null && mCurrentDataset.isActive())
{
if (objectTracker.getActiveDataSet(0).equals(mCurrentDataset)
&& !objectTracker.deactivateDataSet(mCurrentDataset))
{
result = false;
} else if (!objectTracker.destroyDataSet(mCurrentDataset))
{
result = false;
}
mCurrentDataset = null;
}
return result;
}
#Override
public void onInitARDone(SampleApplicationException exception)
{
if (exception == null)
{
initApplicationAR();
mRenderer.mIsActive = true;
// Now add the GL surface view. It is important
// that the OpenGL ES surface view gets added
// BEFORE the camera is started and video
// background is configured.
addContentView(mGlView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
// Sets the UILayout to be drawn in front of the camera
mUILayout.bringToFront();
// Sets the layout background to transparent
mUILayout.setBackgroundColor(Color.TRANSPARENT);
try
{
vuforiaAppSession.startAR(CameraDevice.CAMERA_DIRECTION.CAMERA_DIRECTION_DEFAULT);
} catch (SampleApplicationException e)
{
Log.e(LOGTAG, e.getString());
}
boolean result = CameraDevice.getInstance().setFocusMode(
CameraDevice.FOCUS_MODE.FOCUS_MODE_CONTINUOUSAUTO);
if (result)
mContAutofocus = true;
else
Log.e(LOGTAG, "Unable to enable continuous autofocus");
mSampleAppMenu = new SampleAppMenu(this, this, "Image Targets",
mGlView, mUILayout, null);
setSampleAppMenuSettings();
} else
{
Log.e(LOGTAG, exception.getString());
showInitializationErrorMessage(exception.getString());
}
}
// Shows initialization error messages as System dialogs
private void showInitializationErrorMessage(String message)
{
final String errorMessage = message;
runOnUiThread(new Runnable()
{
public void run()
{
if (mErrorDialog != null)
{
mErrorDialog.dismiss();
}
}
});
}
#Override
public void onVuforiaUpdate(State state)
{
if (mSwitchDatasetAsap)
{
Log.e("onVuforiaUpdate","成功");
mSwitchDatasetAsap = false;
TrackerManager tm = TrackerManager.getInstance();
ObjectTracker ot = (ObjectTracker) tm.getTracker(ObjectTracker
.getClassType());
if (ot == null || mCurrentDataset == null
|| ot.getActiveDataSet(0) == null)
{
Log.d(LOGTAG, "Failed to swap datasets");
return;
}
doUnloadTrackersData();
doLoadTrackersData();
}
}
#Override
public boolean doInitTrackers()
{
// Indicate if the trackers were initialized correctly
boolean result = true;
TrackerManager tManager = TrackerManager.getInstance();
Tracker tracker;
// Trying to initialize the image tracker
tracker = tManager.initTracker(ObjectTracker.getClassType());
if (tracker == null)
{
Log.e(
LOGTAG,
"Tracker not initialized. Tracker already initialized or the camera is already started");
result = false;
} else
{
Log.i(LOGTAG, "Tracker successfully initialized");
}
return result;
}
#Override
public boolean doStartTrackers()
{
// Indicate if the trackers were started correctly
boolean result = true;
Tracker objectTracker = TrackerManager.getInstance().getTracker(
ObjectTracker.getClassType());
if (objectTracker != null)
objectTracker.start();
return result;
}
#Override
public boolean doStopTrackers()
{
// Indicate if the trackers were stopped correctly
boolean result = true;
Tracker objectTracker = TrackerManager.getInstance().getTracker(
ObjectTracker.getClassType());
if (objectTracker != null)
objectTracker.stop();
return result;
}
#Override
public boolean doDeinitTrackers()
{
// Indicate if the trackers were deinitialized correctly
boolean result = true;
TrackerManager tManager = TrackerManager.getInstance();
tManager.deinitTracker(ObjectTracker.getClassType());
return result;
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
// Process the Gestures
if (mSampleAppMenu != null && mSampleAppMenu.processEvent(event))
return true;
return mGestureDetector.onTouchEvent(event);
}
private boolean isExtendedTrackingActive() {
return mExtendedTracking;
}
final public static int CMD_BACK = -1;
final public static int CMD_EXTENDED_TRACKING = 1;
final public static int CMD_AUTOFOCUS = 2;
final public static int CMD_FLASH = 3;
final public static int CMD_CAMERA_FRONT = 4;
final public static int CMD_CAMERA_REAR = 5;
final public static int CMD_DATASET_START_INDEX = 6;
// This method sets the menu's settings
private void setSampleAppMenuSettings()
{
SampleAppMenuGroup group;
group = mSampleAppMenu.addGroup("", false);
group.addTextItem(getString(R.string.menu_back), -1);
group = mSampleAppMenu.addGroup("", true);
group.addSelectionItem(getString(R.string.menu_extended_tracking),
CMD_EXTENDED_TRACKING, false);
group.addSelectionItem(getString(R.string.menu_contAutofocus),
CMD_AUTOFOCUS, mContAutofocus);
mFlashOptionView = group.addSelectionItem(
getString(R.string.menu_flash), CMD_FLASH, false);
Camera.CameraInfo ci = new Camera.CameraInfo();
boolean deviceHasFrontCamera = false;
boolean deviceHasBackCamera = false;
for (int i = 0; i < Camera.getNumberOfCameras(); i++)
{
Camera.getCameraInfo(i, ci);
if (ci.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
deviceHasFrontCamera = true;
else if (ci.facing == Camera.CameraInfo.CAMERA_FACING_BACK)
deviceHasBackCamera = true;
}
if (deviceHasBackCamera && deviceHasFrontCamera)
{
group = mSampleAppMenu.addGroup(getString(R.string.menu_camera),
true);
group.addRadioItem(getString(R.string.menu_camera_front),
CMD_CAMERA_FRONT, false);
group.addRadioItem(getString(R.string.menu_camera_back),
CMD_CAMERA_REAR, true);
}
group = mSampleAppMenu
.addGroup(getString(R.string.menu_datasets), true);
mStartDatasetsIndex = CMD_DATASET_START_INDEX;
mDatasetsNumber = mDatasetStrings.size();
group.addRadioItem("Stones & Chips", mStartDatasetsIndex, true);
group.addRadioItem("Tarmac", mStartDatasetsIndex + 1, false);
mSampleAppMenu.attachMenu();
}
#Override
public boolean menuProcess(int command)
{
boolean result = true;
switch (command)
{
case CMD_BACK:
finish();
break;
case CMD_FLASH:
result = CameraDevice.getInstance().setFlashTorchMode(!mFlash);
if (result)
{
mFlash = !mFlash;
} else
{
showToast(getString(mFlash ? R.string.menu_flash_error_off
: R.string.menu_flash_error_on));
Log.e(LOGTAG,
getString(mFlash ? R.string.menu_flash_error_off
: R.string.menu_flash_error_on));
}
break;
case CMD_AUTOFOCUS:
if (mContAutofocus)
{
result = CameraDevice.getInstance().setFocusMode(
CameraDevice.FOCUS_MODE.FOCUS_MODE_NORMAL);
if (result)
{
mContAutofocus = false;
} else
{
showToast(getString(R.string.menu_contAutofocus_error_off));
Log.e(LOGTAG,
getString(R.string.menu_contAutofocus_error_off));
}
} else
{
result = CameraDevice.getInstance().setFocusMode(
CameraDevice.FOCUS_MODE.FOCUS_MODE_CONTINUOUSAUTO);
if (result)
{
mContAutofocus = true;
} else
{
showToast(getString(R.string.menu_contAutofocus_error_on));
Log.e(LOGTAG,
getString(R.string.menu_contAutofocus_error_on));
}
}
break;
case CMD_CAMERA_FRONT:
case CMD_CAMERA_REAR:
// Turn off the flash
if (mFlashOptionView != null && mFlash)
{
// OnCheckedChangeListener is called upon changing the checked state
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
{
((Switch) mFlashOptionView).setChecked(false);
} else
{
((CheckBox) mFlashOptionView).setChecked(false);
}
}
vuforiaAppSession.stopCamera();
try
{
vuforiaAppSession
.startAR(command == CMD_CAMERA_FRONT ? CameraDevice.CAMERA_DIRECTION.CAMERA_DIRECTION_FRONT
: CameraDevice.CAMERA_DIRECTION.CAMERA_DIRECTION_BACK);
} catch (SampleApplicationException e)
{
showToast(e.getString());
Log.e(LOGTAG, e.getString());
result = false;
}
doStartTrackers();
break;
case CMD_EXTENDED_TRACKING:
for (int tIdx = 0; tIdx < mCurrentDataset.getNumTrackables(); tIdx++)
{
Trackable trackable = mCurrentDataset.getTrackable(tIdx);
if (!mExtendedTracking)
{
if (!trackable.startExtendedTracking())
{
Log.e(LOGTAG,
"Failed to start extended tracking target");
result = false;
} else
{
Log.d(LOGTAG,
"Successfully started extended tracking target");
}
} else
{
if (!trackable.stopExtendedTracking())
{
Log.e(LOGTAG,
"Failed to stop extended tracking target");
result = false;
} else
{
Log.d(LOGTAG,
"Successfully started extended tracking target");
}
}
}
if (result)
mExtendedTracking = !mExtendedTracking;
break;
default:
if (command >= mStartDatasetsIndex
&& command < mStartDatasetsIndex + mDatasetsNumber)
{
mSwitchDatasetAsap = true;
mCurrentDatasetSelectionIndex = command
- mStartDatasetsIndex;
}
break;
}
return result;
}
private void showToast(String text)
{
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
}
Related
i made a googlemap app where my markers are displyed.
the problem is when there no internet, the app is crashing. The code under onResume does not solve the problem.
also i want to refresh the map or markers each second on the map.
if you have any ideas please i am here to learn from all of you.
here is my MapActivity code :
public class MapActivity extends AppCompatActivity implements OnMapReadyCallback
{
private static final String TAG = "MapActivity";
#Bind(R.id.back)
View back;
#Bind(R.id.zoom_in)
View zoom_in;
#Bind(R.id.zoom_out)
View zoom_out;
#Bind(R.id.updatetimer)
TextView updatetimer;
#Bind(R.id.autozoom)
ImageView autozoom;
#Bind(R.id.showtails)
ImageView showtails;
#Bind(R.id.geofences)
ImageView showGeofences;
#Bind(R.id.map_layer)
ImageView map_layer_icon;
private GoogleMap map;
#Bind(R.id.content_layout)
View content_layout;
#Bind(R.id.loading_layout)
View loading_layout;
#Bind(R.id.nodata_layout)
View nodata_layout;
private Timer timer;
private int autoZoomedTimes = 0;// dėl bugo osmdroid library, zoom'inam du kartus ir paskui po refresh'o nebe, nes greičiausiai user'is bus pakeitęs zoom'ą
private HashMap<Integer, Marker> deviceIdMarkers;
private HashMap<String, Device> markerIdDevices;
private HashMap<Integer, Polyline> deviceIdPolyline;
private HashMap<Integer, LatLng> deviceIdLastLatLng;
// private HashMap<Integer, Marker> deviceIdSmallMarkerInfo;
private long lastRefreshTime;
boolean isAutoZoomEnabled = true;
boolean isShowTitlesEnabled;
boolean isShowTailsEnabled = true;
boolean isShowGeofencesEnabled = true;
private String stopTime;
private AsyncTask downloadingAsync;
private boolean isRefreshLoced = false;
ApiInterface.GetGeofencesResult geofencesResult;
ArrayList<PolygonWithName> polygonsWithDetails = new ArrayList<>();
float previousZoomLevel = 0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
ButterKnife.bind(this);
deviceIdMarkers = new HashMap<>();
markerIdDevices = new HashMap<>();
deviceIdPolyline = new HashMap<>();
deviceIdLastLatLng = new HashMap<>();
// deviceIdSmallMarkerInfo = new HashMap<>();
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
protected void onResume()
{
super.onResume();
timer = new Timer();
timer.schedule(new TimerTask()
{
#Override
public void run()
{
runOnUiThread(new Runnable()
{
#Override
public void run()
{
float timeleft = 10 - Math.round(System.currentTimeMillis() - lastRefreshTime) / 1000f;
if (timeleft < 0)
timeleft = 0;
updatetimer.setText(String.format("%.0f", timeleft));
if (System.currentTimeMillis() - lastRefreshTime >= 10 * 1000)
if (map != null)
refresh();
}
});
}
}, 0, 1000);
}
#Override
protected void onPause()
{
super.onPause();
try
{
timer.cancel();
timer.purge();
downloadingAsync.cancel(true);
} catch (Exception e)
{
e.printStackTrace();
}
}
private void refresh()
{
if (isRefreshLoced)
return;
isRefreshLoced = true;
lastRefreshTime = System.currentTimeMillis();
final String api_key = (String) DataSaver.getInstance(this).load("api_key");
API.getApiInterface(this).getDevices(api_key, getResources().getString(R.string.lang), new Callback<ArrayList<ApiInterface.GetDevicesItem>>()
{
#Override
public void success(final ArrayList<ApiInterface.GetDevicesItem> getDevicesItems, Response response)
{
Log.d(TAG, "success: loaded devices array");
final ArrayList<Device> allDevices = new ArrayList<>();
if (getDevicesItems != null)
for (ApiInterface.GetDevicesItem item : getDevicesItems)
allDevices.addAll(item.items);
API.getApiInterface(MapActivity.this).getFieldsDataForEditing(api_key, getResources().getString(R.string.lang), 1, new Callback<ApiInterface.GetFieldsDataForEditingResult>()
{
#Override
public void success(final ApiInterface.GetFieldsDataForEditingResult getFieldsDataForEditingResult, Response response)
{
Log.d(TAG, "success: loaded icons");
downloadingAsync = new AsyncTask<Void, Void, Void>()
{
ArrayList<MarkerOptions> markers;
ArrayList<Integer> deviceIds;
#Override
protected Void doInBackground(Void... params)
{
// add markers
int dp100 = Utils.dpToPx(MapActivity.this, 50);
markers = new ArrayList<>();
deviceIds = new ArrayList<>();
if (getFieldsDataForEditingResult == null || getFieldsDataForEditingResult.device_icons == null)
return null;
for (Device item : allDevices)
{
if (isCancelled())
break;
if (item.device_data.active == 1)
{
// ieškom ikonos masyve
DeviceIcon mapIcon = null;
for (DeviceIcon icon : getFieldsDataForEditingResult.device_icons)
if (item.device_data.icon_id == icon.id)
mapIcon = icon;
String server_base = (String) DataSaver.getInstance(MapActivity.this).load("server_base");
try
{
Log.d("MapActivity", "DOWNLOADING BITMAP: " + server_base + mapIcon.path);
Bitmap bmp = BitmapFactory.decodeStream(new URL(server_base + mapIcon.path).openConnection().getInputStream());
int srcWidth = bmp.getWidth();
int srcHeight = bmp.getHeight();
int maxWidth = Utils.dpToPx(MapActivity.this, mapIcon.width);
int maxHeight = Utils.dpToPx(MapActivity.this, mapIcon.height);
float ratio = Math.min((float) maxWidth / (float) srcWidth, (float) maxHeight / (float) srcHeight);
int dstWidth = (int) (srcWidth * ratio);
int dstHeight = (int) (srcHeight * ratio);
bmp = bmp.createScaledBitmap(bmp, dp100, dp100, true);
// marker
MarkerOptions m = new MarkerOptions();
m.position(new LatLng(item.lat, item.lng));
// marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
// marker.setIcon(new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bmp, dstWidth, dstHeight, true)));
m.icon(BitmapDescriptorFactory.fromBitmap(Bitmap.createScaledBitmap(bmp, dstWidth, dstHeight, true)));
// info window
// MapMarkerInfoWindow infoWindow = new MapMarkerInfoWindow(MapActivity.this, item, R.layout.layout_map_infowindow, map);
// marker.setInfoWindow(infoWindow);
markers.add(m);
deviceIds.add(item.id);
} catch (OutOfMemoryError outOfMemoryError)
{
Toast.makeText(MapActivity.this, "Out of memory! Too many devices are selected to be displayed", Toast.LENGTH_LONG).show();
} catch (Exception e)
{
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void aVoid)
{
ArrayList<GeoPoint> points = new ArrayList<>();
if (autoZoomedTimes < 1)
{
new Handler().postDelayed(new Runnable()
{
#Override
public void run()
{
runOnUiThread(new Runnable()
{
#Override
public void run()
{
if (markers.size() > 1)
{
try
{
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (MarkerOptions item : markers)
builder.include(item.getPosition());
LatLngBounds bounds = builder.build();
// int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, Utils.dpToPx(MapActivity.this, 50));
map.animateCamera(cu);
} catch (Exception e)
{
}
} else if (markers.size() > 0)
{
map.moveCamera(CameraUpdateFactory.newLatLngZoom(markers.get(0).getPosition(), 15));
}
autoZoomedTimes++;
}
});
}
}, 50);
} else if (isAutoZoomEnabled)
{
if (markers.size() > 1)
{
try
{
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (MarkerOptions item : markers)
builder.include(item.getPosition());
LatLngBounds bounds = builder.build();
// int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, Utils.dpToPx(MapActivity.this, 50));
map.animateCamera(cu);
} catch (Exception e)
{
}
} else if (markers.size() > 0)
{
map.moveCamera(CameraUpdateFactory.newLatLngZoom(markers.get(0).getPosition(), 15));
}
autoZoomedTimes++;
}
Log.d(TAG, "onPostExecute: icons downloaded and added to map, total markers: " + markers.size());
loading_layout.setVisibility(View.GONE);
if (markers.size() != 0)
content_layout.setVisibility(View.VISIBLE);
else
nodata_layout.setVisibility(View.VISIBLE);
for (int i = 0; i < markers.size(); i++)
{
MarkerOptions options = markers.get(i);
int deviceId = deviceIds.get(i);
Marker m;
Polyline polyline;
if (deviceIdMarkers.containsKey(deviceId))
{
Log.d("aa", "moving to" + options.getPosition());
deviceIdMarkers.get(deviceId).setPosition(new LatLng(options.getPosition().latitude, options.getPosition().longitude));
m = deviceIdMarkers.get(deviceId);
polyline = deviceIdPolyline.get(deviceId);
} else
{
Log.d("aa", "putting new");
m = map.addMarker(options);
deviceIdMarkers.put(deviceId, m);
polyline = map.addPolyline(new PolylineOptions());
deviceIdPolyline.put(deviceId, polyline);
}
Device thatonedevice = null;
for (Device device : allDevices)
if (device.id == deviceId)
thatonedevice = device;
markerIdDevices.put(m.getId(), thatonedevice);
// update marker rotation based on driving direction
if (thatonedevice != null && deviceIdLastLatLng.containsKey(deviceId))
{
double dirLat = thatonedevice.lat - deviceIdLastLatLng.get(deviceId).latitude;
double dirLng = thatonedevice.lng - deviceIdLastLatLng.get(deviceId).longitude;
m.setRotation((float) Math.toDegrees(Math.atan2(dirLng, dirLat)));
}
deviceIdLastLatLng.put(deviceId, new LatLng(thatonedevice.lat, thatonedevice.lng));
List<LatLng> polylinePoints = new ArrayList<>();
for (TailItem item : thatonedevice.tail)
polylinePoints.add(new LatLng(Double.valueOf(item.lat), Double.valueOf(item.lng)));
polyline.setPoints(polylinePoints);
polyline.setWidth(Utils.dpToPx(MapActivity.this, 2));
polyline.setColor(Color.parseColor(thatonedevice.device_data.tail_color));
}
// else
map.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter()
{
#Override
public View getInfoWindow(Marker marker)
{
return null;
}
#Override
public View getInfoContents(final Marker marker)
{
synchronized (this)
{
}
final Device device = markerIdDevices.get(marker.getId());
if (device != null)
{
View view = getLayoutInflater().inflate(R.layout.layout_map_infowindow, null);
view.bringToFront();
view.findViewById(R.id.close).setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
marker.hideInfoWindow();
}
});
TextView device_name = (TextView) view.findViewById(R.id.device_name);
device_name.setText(device.name);
TextView altitude = (TextView) view.findViewById(R.id.altitude);
altitude.setText(String.valueOf(device.altitude) + " " + device.unit_of_altitude);
TextView time = (TextView) view.findViewById(R.id.time);
time.setText(device.time);
TextView stopTimeView = (TextView) view.findViewById(R.id.stopTime);
stopTimeView.setText(stopTime);
TextView speed = (TextView) view.findViewById(R.id.speed);
speed.setText(device.speed + " " + device.distance_unit_hour);
TextView address = (TextView) view.findViewById(R.id.address);
address.setText(device.address);
final ArrayList<Sensor> showableSensors = new ArrayList<>();
for (Sensor item : device.sensors)
if (item.show_in_popup > 0)
showableSensors.add(item);
ListView sensors_list = (ListView) view.findViewById(R.id.sensors_list);
sensors_list.setAdapter(new AwesomeAdapter<Sensor>(MapActivity.this)
{
#Override
public int getCount()
{
return showableSensors.size();
}
#NonNull
#Override
public View getView(int position, View convertView, #NonNull ViewGroup parent)
{
if (convertView == null)
convertView = getLayoutInflater().inflate(R.layout.adapter_map_sensorslist, null);
Sensor item = showableSensors.get(position);
TextView name = (TextView) convertView.findViewById(R.id.name);
name.setText(item.name);
TextView value = (TextView) convertView.findViewById(R.id.value);
value.setText(item.value);
return convertView;
}
});
List<Address> addresses;
try
{
addresses = new Geocoder(MapActivity.this).getFromLocation(device.lat, device.lng, 1);
if (addresses.size() > 0)
address.setText(addresses.get(0).getAddressLine(0));
} catch (IOException e)
{
e.printStackTrace();
}
return view;
}
return null;
}
});
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()
{
#Override
public boolean onMarkerClick(final Marker marker)
{
int px = Utils.dpToPx(MapActivity.this, 300);
map.setPadding(0, px, 0, 0);
stopTime = "...";
final Device device = markerIdDevices.get(marker.getId());
if (device != null)
{
API.getApiInterface(MapActivity.this).deviceStopTime((String) DataSaver.getInstance(MapActivity.this).load("api_key"), "en", device.id, new Callback<ApiInterface.DeviceStopTimeResult>()
{
#Override
public void success(ApiInterface.DeviceStopTimeResult result, Response response)
{
stopTime = result.time;
marker.showInfoWindow();
}
#Override
public void failure(RetrofitError retrofitError)
{
Toast.makeText(MapActivity.this, R.string.errorHappened, Toast.LENGTH_SHORT).show();
}
});
}
return false;
}
});
map.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener()
{
#Override
public void onInfoWindowClick(Marker marker)
{
marker.hideInfoWindow();
}
});
map.setOnInfoWindowCloseListener(new GoogleMap.OnInfoWindowCloseListener()
{
#Override
public void onInfoWindowClose(Marker marker)
{
map.setPadding(0, 0, 0, 0);
}
});
// updateSmallMarkerData(allDevices);
isRefreshLoced = false;
}
}.execute();
}
#Override
public void failure(RetrofitError retrofitError)
{
Toast.makeText(MapActivity.this, R.string.errorHappened, Toast.LENGTH_SHORT).show();
isRefreshLoced = false;
}
});
}
#Override
public void failure(RetrofitError retrofitError)
{
Toast.makeText(MapActivity.this, R.string.errorHappened, Toast.LENGTH_SHORT).show();
isRefreshLoced = false;
}
});
}
#Override
public void onMapReady(GoogleMap googleMap)
{
map = googleMap;
refresh();
}
this MapActivity is slow to load, could you teach me a way to make it goes faster?
Best regard :)
waiting for your propositions.
PS: i have removed some functions to make the code look short but i kept the most important in is case.
For the crashing issue
create a class
public class NetWorkChecker {
static NetworkInfo wifi, mobile;
public static Boolean check(Context c) {
ConnectivityManager cm = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
try {
wifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
mobile = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
} catch (Exception e) {
e.printStackTrace();
}
if (wifi != null && wifi.isConnected() && wifi.isAvailable()) {
return true;
} else if (mobile != null && mobile.isAvailable() && mobile.isConnected()) {
return true;
} else {
//Toast.makeText(c, "No Network Connection", Toast.LENGTH_SHORT).show();
// ((Activity) c).finish();
displayMobileDataSettingsDialog(c,"No Network Connection","No Network Connection");
return false;
}
}
public static AlertDialog displayMobileDataSettingsDialog(final Context context, String title, String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(title);
builder.setMessage(message);
builder.setCancelable(false);
builder.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
context.startActivity(intent);
}
});
builder.show();
return builder.create();
}
}
to check if the devise have an active internet connection
call
if (!NetWorkChecker.check(this)){
////do your refres
}
public class MainActivity extends AppCompatActivity {
/* access modifiers changed from: private */
public int choosingUriFor;
private int playTime;
/* access modifiers changed from: private */
public Uri playerURI1;
/* access modifiers changed from: private */
public Uri playerURI2;
ActivityResultLauncher<String> startGallery = registerForActivityResult(new ActivityResultContracts.GetContent(), new ActivityResultCallback<Uri>() {
/* JADX WARNING: type inference failed for: r0v0, types: [android.content.Context, edu.miami.cs.geoff.tictactoc.MainActivity] */
public void onActivityResult(Uri resultUri) {
if (resultUri != null) {
Drawable convertURIToDrawable = MainActivity.convertURIToDrawable(MainActivity.this, resultUri);
Drawable image = convertURIToDrawable;
if (convertURIToDrawable == null) {
return;
}
if (MainActivity.this.choosingUriFor == 1) {
((Button) MainActivity.this.findViewById(R.id.player_image1)).setForeground(image);
Uri unused = MainActivity.this.playerURI1 = resultUri;
return;
}
((Button) MainActivity.this.findViewById(R.id.player_image2)).setForeground(image);
Uri unused2 = MainActivity.this.playerURI2 = resultUri;
}
}
});
ActivityResultLauncher<Intent> startPlaying = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
public void onActivityResult(ActivityResult result) {
int winner;
RatingBar winnerBar;
if (result.getResultCode() == -1 && (winner = result.getData().getIntExtra("edu.miami.cs.geoff.tictactoc.winner", 0)) > 0) {
if (winner == 1) {
winnerBar = (RatingBar) MainActivity.this.findViewById(R.id.player_score1);
} else {
winnerBar = (RatingBar) MainActivity.this.findViewById(R.id.player_score2);
}
winnerBar.setRating(winnerBar.getRating() + 1.0f);
if (winnerBar.getRating() == ((float) winnerBar.getNumStars())) {
MainActivity.this.findViewById(R.id.start_game_button).setVisibility(View.INVISIBLE);
}
}
}
});
private double startSplit = 0.5d;
/* access modifiers changed from: protected */
public void onCreate(Bundle savedInstanceState) {
MainActivity.super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.playTime = getResources().getInteger(R.integer.medium_ms);
}
/* JADX WARNING: type inference failed for: r7v0, types: [android.content.Context, edu.miami.cs.geoff.tictactoc.MainActivity] */
public void myClickHandler(View view) {
int starter;
switch (view.getId()) {
case R.id.playing_image1:
this.choosingUriFor = 1;
this.startGallery.launch("image/*");
return;
case R.id.playing_image2:
this.choosingUriFor = 2;
this.startGallery.launch("image/*");
return;
case R.id.start_game_button:
Intent playActivity = new Intent(this, TicTacTocPlay.class);
playActivity.putExtra("edu.miami.cs.geoff.tictactoc.player_name1", getPlayerName(R.id.player_name1));
playActivity.putExtra("edu.miami.cs.geoff.tictactoc.player_image1", this.playerURI1);
playActivity.putExtra("edu.miami.cs.geoff.tictactoc.player_name2", getPlayerName(R.id.player_name2));
playActivity.putExtra("edu.miami.cs.geoff.tictactoc.player_image2", this.playerURI2);
playActivity.putExtra("edu.miami.cs.geoff.tictactoc.play_time", this.playTime);
double random = Math.random();
double d = this.startSplit;
if (random > d) {
starter = 2;
this.startSplit = d + 0.1d;
} else {
starter = 1;
this.startSplit = d - 0.1d;
}
playActivity.putExtra("edu.miami.cs.geoff.tictactoc.go_first", starter);
this.startPlaying.launch(playActivity);
return;
default:
return;
}
}
private String getPlayerName(int playerId) {
String name = ((EditText) findViewById(playerId)).getText().toString();
if (name != null && !name.equals("")) {
return name;
}
if (playerId == R.id.player_name1) {
return getResources().getString(R.string.default_name_1);
}
return getResources().getString(R.string.default_name_2);
}
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.score_menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.play_fast_item:
this.playTime = getResources().getInteger(R.integer.fast_ms);
return true;
case R.id.play_medium_item:
this.playTime = getResources().getInteger(R.integer.medium_ms);
return true;
case R.id.play_slow_item:
this.playTime = getResources().getInteger(R.integer.slow_ms);
return true;
case R.id.play_flash_item:
this.playTime = getResources().getInteger(R.integer.flash_ms);
return true;
case R.id.reset_item:
((RatingBar) findViewById(R.id.player_score1)).setRating(0.0f);
((RatingBar) findViewById(R.id.player_score2)).setRating(0.0f);
findViewById(R.id.start_game_button).setVisibility(View.VISIBLE);
return true;
default:
return MainActivity.super.onOptionsItemSelected(item);
}
}
public static Drawable convertURIToDrawable(Context context, Uri myURI) {
try {
return Drawable.createFromStream(context.getContentResolver().openInputStream(myURI), myURI.toString());
} catch (Exception e) {
return null;
}
}
}
Above is the MainActivity in AndroidStudio. I got parcel size error first now I got On click error while trying to debug. I'm so lost. I assume the error is in the TicTacTocPLay class especially in the runnable and run method. But i still havent been able to pinpoint the error. So, in the main method there is a play button which should direct to the second activity which is the TicTacTocPlay class. In the emulator the app crashes when I press play.
public class TicTacTocPlay extends AppCompatActivity {
private int[][] board = ((int[][]) Array.newInstance(int.class, new int[]{3, 3}));
/* access modifiers changed from: private */
public Handler myHandler = new Handler();
/* access modifiers changed from: private */
public final Runnable myProgresser = new Runnable() {
private int whoseTurnLast = 0;
public void run() {
if (this.whoseTurnLast != TicTacTocPlay.this.whoseTurn) {
TicTacTocPlay.this.myHandler.removeCallbacks(TicTacTocPlay.this.myProgresser);
TicTacTocPlay.this.playTimer.setProgress(TicTacTocPlay.this.playTime);
this.whoseTurnLast = TicTacTocPlay.this.whoseTurn;
} else {
TicTacTocPlay.this.playTimer.setProgress(TicTacTocPlay.this.playTimer.getProgress() - TicTacTocPlay.this.playClickTime);
}
if (TicTacTocPlay.this.playTimer.getProgress() == 0) {
TicTacTocPlay ticTacTocPlay = TicTacTocPlay.this;
int unused = ticTacTocPlay.whoseTurn = (ticTacTocPlay.whoseTurn % 2) + 1;
TicTacTocPlay.this.startPlayer();
} else if (!TicTacTocPlay.this.myHandler.postDelayed(TicTacTocPlay.this.myProgresser, (long) TicTacTocPlay.this.playClickTime)) {
Log.e("ERROR", "Cannot postDelayed");
}
}
};
private int numberOfPlays;
/* access modifiers changed from: private */
public int playClickTime;
/* access modifiers changed from: private */
public int playTime;
/* access modifiers changed from: private */
public ProgressBar playTimer;
private Drawable[] playerImages = new Drawable[2];
private String[] playerNames = new String[2];
/* access modifiers changed from: private */
public int whoseTurn;
/* access modifiers changed from: protected */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tic_tac_toc_play);
initializeGame(getIntent());
startPlayer();
}
/* JADX WARNING: type inference failed for: r4v0, types: [android.content.Context, edu.miami.cs.geoff.tictactoc.TicTacTocPlay] */
private void initializeGame(Intent dataFromLaunch) {
this.playerNames[0] = dataFromLaunch.getStringExtra("edu.miami.cs.geoff.tictactoc.player_name1");
this.playerNames[1] = dataFromLaunch.getStringExtra("edu.miami.cs.geoff.tictactoc.player_name2");
this.playerImages[0] = MainActivity.convertURIToDrawable(this, (Uri) dataFromLaunch.getParcelableExtra("edu.miami.cs.geoff.tictactoc.player_image1"));
this.playerImages[1] = MainActivity.convertURIToDrawable(this, (Uri) dataFromLaunch.getParcelableExtra("edu.miami.cs.geoff.tictactoc.player_image2"));
setButton(R.id.playing_image1, 1);
setButton(R.id.playing_image2, 2);
this.whoseTurn = dataFromLaunch.getIntExtra("edu.miami.cs.geoff.tictactoc.go_first", 0);
int intExtra = dataFromLaunch.getIntExtra("edu.miami.cs.geoff.tictactoc.play_time", 0);
this.playTime = intExtra;
this.playClickTime = intExtra / 20;
ProgressBar progressBar = (ProgressBar) findViewById(R.id.play_time);
this.playTimer = progressBar;
progressBar.setMax(this.playTime);
this.numberOfPlays = 0;
}
/* access modifiers changed from: private */
public void startPlayer() {
Button watcherButton;
Button playerButton;
if (this.whoseTurn == 1) {
playerButton = (Button) findViewById(R.id.playing_image1);
watcherButton = (Button) findViewById(R.id.playing_image2);
} else {
playerButton = (Button) findViewById(R.id.playing_image2);
watcherButton = (Button) findViewById(R.id.playing_image1);
}
playerButton.setVisibility(View.VISIBLE);
watcherButton.setVisibility(View.INVISIBLE);
((TextView) findViewById(R.id.player_name)).setText(this.playerNames[this.whoseTurn - 1]);
this.myProgresser.run();
}
public void myClickHandler(View view) {
switch (view.getId()) {
case R.id.Button00:
setButtonAndPlay(0, 0, view.getId());
return;
case R.id.Button01:
setButtonAndPlay(0, 1, view.getId());
return;
case R.id.Button02:
setButtonAndPlay(0, 2, view.getId());
return;
case R.id.Button10:
setButtonAndPlay(1, 0, view.getId());
return;
case R.id.Button11:
setButtonAndPlay(1, 1, view.getId());
return;
case R.id.Button12:
setButtonAndPlay(1, 2, view.getId());
return;
case R.id.Button20:
setButtonAndPlay(2, 0, view.getId());
return;
case R.id.Button21:
setButtonAndPlay(2, 1, view.getId());
return;
case R.id.Button22:
setButtonAndPlay(2, 2, view.getId());
return;
default:
return;
}
}
/* access modifiers changed from: package-private */
public void setButtonAndPlay(int row, int column, int playedButtonId) {
if (this.board[row][column] == 0) {
this.numberOfPlays++;
setButton(playedButtonId, this.whoseTurn);
this.board[row][column] = this.whoseTurn;
if (!endOfGame(row, column)) {
this.whoseTurn = (this.whoseTurn % 2) + 1;
startPlayer();
}
}
}
private void setButton(int buttonId, int playerIndex) {
Log.i("DEBUG", "Setting button for player " + playerIndex);
if (this.playerImages[playerIndex - 1] != null) {
Log.i("DEBUG", "Setting button for player " + playerIndex + " to an image");
findViewById(buttonId).setForeground(this.playerImages[playerIndex + -1]);
} else if (playerIndex == 1) {
Log.i("DEBUG", "Setting button for player 1 to RED");
findViewById(buttonId).setForeground(ResourcesCompat.getDrawable(getResources(), R.drawable.red_button, (Resources.Theme) null));
} else {
Log.i("DEBUG", "Setting button for player 2 to GREEN");
findViewById(buttonId).setForeground(ResourcesCompat.getDrawable(getResources(), R.drawable.green_button, (Resources.Theme) null));
}
}
private boolean endOfGame(int row, int column) {
int winner;
int antiDiagonalWin = 0;
int diagonalWin = 0;
int columnWin = 0;
int rowWin = 0;
for (int index = 0; index < 3; index++) {
int[][] iArr = this.board;
int i = iArr[row][index];
int i2 = this.whoseTurn;
if (i == i2) {
rowWin++;
}
if (iArr[index][column] == i2) {
columnWin++;
}
if (iArr[index][index] == i2) {
diagonalWin++;
}
if (iArr[index][2 - index] == i2) {
antiDiagonalWin++;
}
}
if (rowWin == 3 || columnWin == 3 || diagonalWin == 3 || antiDiagonalWin == 3) {
winner = this.whoseTurn;
} else if (this.numberOfPlays == 9) {
winner = 0;
} else {
winner = -1;
}
if (winner < 0) {
return false;
}
Intent returnIntent = new Intent();
returnIntent.putExtra("edu.miami.cs.geoff.tictactoc.winner", winner);
setResult(-1, returnIntent);
finish();
return true;
}
/* access modifiers changed from: protected */
public void onDestroy() {
TicTacTocPlay.super.onDestroy();
this.myHandler.removeCallbacks(this.myProgresser);
}
}
I'm new to Android app developing, and I've tried to program a very simple app: each time the headphone cable is inserted it will play a random song from the collection, and stop whenever the headphone cable is disconnected.
However, I now face a very strange problem: no matter what I do, the app plays always two songs at the same time.
It's very strange because I tried to synchronize everything but it didn't solve the issue...
Here follows my code. Thanks in advance for any help!
public class MainActivity extends AppCompatActivity {
private int countMusic;
private boolean headphones= false;
private HeadphonePlugReceiver receiver;
private HashMap<Integer, String> playing_title;
private RandomPlayer player;
Object lock = new Object();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playing_title = new HashMap<>();
scanAgain();
Button scanButton = (Button)findViewById(R.id.scan_again);
scanButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
scanAgain();
}
});
updateStatus();
receiver = new HeadphonePlugReceiver();
registerReceiver(receiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
}
private void updateStatus() {
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView statusTextView = (TextView)findViewById(R.id.status);
TextView titleTextView = (TextView)findViewById(R.id.title);
if (headphones) {
statusTextView.setText("Headphones connected!");
String txt = "";
for (Integer cd: playing_title.keySet()) {
txt += String.format("%d: %s ### ", cd, playing_title.get(cd).replace("_", " "));
}
titleTextView.setText(txt);
} else {
statusTextView.setText("Headphones not connected.");
titleTextView.setText("Music not playing");
}
}
});
}
private void addDebug(final String code) {
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView debugTextView = (TextView)findViewById(R.id.debug);
String dbg = String.format("%s \n %s", debugTextView.getText(), code);
debugTextView.setText(dbg);
}
});
}
private void addError(final String msg) {
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView errorTextView = (TextView)findViewById(R.id.error);
errorTextView.setText(msg);
}
});
}
private void startPlayer() {
if (player == null) {
player = new RandomPlayer(this);
player.start();
}
}
private void stopPlayer() {
if (player != null) {
player.interr();
player = null;
}
}
private void scanAgain() {
try {
TextView countTextView = (TextView)findViewById(R.id.count);
countTextView.setText("Scanning... ");
countMusic = scanMusic().getCount();
countTextView.setText(String.format("Music file found: %d", countMusic));
}
catch(Exception e) {
Log.e("problem", e.getMessage());
}
}
public Cursor scanMusic() {
ContentResolver cr = this.getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
String[] projection = {
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.TITLE_KEY
};
Cursor cur = cr.query(uri, projection, selection, null, sortOrder);
return cur;
}
private class HeadphonePlugReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
synchronized (lock) {
int state = intent.getIntExtra("state", 0);
managePlayer(state);
// Log.e("state", String.format("state: %d", state));
}
}
private void managePlayer(int state) {
boolean n_headphones = (state != 0);
if (n_headphones == headphones)
return;
headphones = n_headphones;
if (headphones)
startPlayer();
else
stopPlayer();
}
}
private class RandomPlayer extends Thread implements MediaPlayer.OnCompletionListener {
private final MainActivity act;
private final Random r;
private final int code;
private MediaPlayer mp;
private boolean keep_going = true;
Object lock2 = new Object();
public RandomPlayer(MainActivity mainActivity) {
r = new Random(System.currentTimeMillis());
act = mainActivity;
code = r.nextInt(10000);
}
public void onCompletion(MediaPlayer arg0) {
playNext();
}
#Override
public void run() {
playNext();
while (keep_going) {
try {
sleep(100);
} catch (InterruptedException e) {
keep_going = false;
}
}
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
playing_title.remove(code);
updateStatus();
}
public void interr() {
keep_going = false;
}
private void playNext() {
synchronized (lock2) {
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
//mp.setVolume(0.9f , 0.9f);
mp.setOnCompletionListener(this);
int chosen = r.nextInt(countMusic);
Cursor cur = scanMusic();
for (int i = 0; i < chosen; i++)
cur.moveToNext();
playing_title.put(code, cur.getString(cur.getColumnIndex(MediaStore.Audio.Media.TITLE)));
try {
int a1 = cur.getColumnIndex(MediaStore.Audio.Media.DATA);
String a2 = cur.getString(a1);
mp.setDataSource(a2);
mp.prepare();
mp.start();
addDebug(a2);
} catch (Exception e) {
Log.e("Randomplayer", "exception", e);
addError(e.getMessage());
}
updateStatus();
}
}
}
}
How can I put the result of the QR "SCAN_RESULT" in different activity, this is my problem.
In the splash screen I need to go to the QRScanner (CaptureActivity), and then, to the ActivityQR who will send the info. to the SQLite.
The problem is: When I get de QRCode in string ("SCAN_RESULT") on "CaptureActivity.java", the app close because the app need "back" to the previous activity with this:
getIntent();
I try to modify this codeline, but this not solve my problem.
How can I put the "SCAN_RESULT" in the ActivityQR? I don't know how open other activity (this case ActivityQR) when the code had gottenm and put this String value on the ActivityQR
I Use "CaptureActivity" of ZXing (ZebraCrossing)
Thanks in advance.
SplashScreen.java :
{
Intent mainIntent = new Intent().setClass(SplashScreenActivity.this, com.google.zxing.client.android.CaptureActivity.class);
startActivity(mainIntent)
}
ActivityQR.java
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
if(REQUEST_CODE == requestCode && RESULT_OK == resultCode){
txResult.setText(data.getStringExtra("SCAN_RESULT"));
}
}
CaptureActivity.java
public class CaptureActivity extends Activity implements SurfaceHolder.Callback {
private static final String TAG = CaptureActivity.class.getSimpleName();
private static final long DEFAULT_INTENT_RESULT_DURATION_MS = 1500L;
private static final long BULK_MODE_SCAN_DELAY_MS = 1000L;
private static final String[] ZXING_URLS = { "http://zxing.appspot.com/scan", "zxing://scan/" };
public static final int HISTORY_REQUEST_CODE = 0x0000bacc;
private static final Collection<ResultMetadataType> DISPLAYABLE_METADATA_TYPES =
EnumSet.of(ResultMetadataType.ISSUE_NUMBER,
ResultMetadataType.SUGGESTED_PRICE,
ResultMetadataType.ERROR_CORRECTION_LEVEL,
ResultMetadataType.POSSIBLE_COUNTRY);
private CameraManager cameraManager;
private CaptureActivityHandler handler;
private Result savedResultToShow;
private ViewfinderView viewfinderView;
private TextView statusView;
private View resultView;
private Result lastResult;
private boolean hasSurface;
private boolean copyToClipboard;
private IntentSource source;
private String sourceUrl;
private ScanFromWebPageManager scanFromWebPageManager;
private Collection<BarcodeFormat> decodeFormats;
private Map<DecodeHintType,?> decodeHints;
private String characterSet;
private HistoryManager historyManager;
private InactivityTimer inactivityTimer;
private BeepManager beepManager;
private AmbientLightManager ambientLightManager;
ViewfinderView getViewfinderView() {
return viewfinderView;
}
public Handler getHandler() {
return handler;
}
CameraManager getCameraManager() {
return cameraManager;
}
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.capture);
hasSurface = false;
historyManager = new HistoryManager(this);
historyManager.trimHistory();
inactivityTimer = new InactivityTimer(this);
beepManager = new BeepManager(this);
ambientLightManager = new AmbientLightManager(this);
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
}
#Override
protected void onResume() {
super.onResume();
// CameraManager must be initialized here, not in onCreate(). This is necessary because we don't
// want to open the camera driver and measure the screen size if we're going to show the help on
// first launch. That led to bugs where the scanning rectangle was the wrong size and partially
// off screen.
cameraManager = new CameraManager(getApplication());
viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
viewfinderView.setCameraManager(cameraManager);
resultView = findViewById(R.id.result_view);
statusView = (TextView) findViewById(R.id.status_view);
handler = null;
lastResult = null;
resetStatusView();
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) {
// The activity was paused but not stopped, so the surface still exists. Therefore
// surfaceCreated() won't be called, so init the camera here.
initCamera(surfaceHolder);
} else {
// Install the callback and wait for surfaceCreated() to init the camera.
surfaceHolder.addCallback(this);
}
beepManager.updatePrefs();
ambientLightManager.start(cameraManager);
inactivityTimer.onResume();
Intent intent = getIntent();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
copyToClipboard = prefs.getBoolean(PreferencesActivity.KEY_COPY_TO_CLIPBOARD, true)
&& (intent == null || intent.getBooleanExtra(Intents.Scan.SAVE_HISTORY, true));
source = IntentSource.NONE;
decodeFormats = null;
characterSet = null;
if (intent != null) {
String action = intent.getAction();
String dataString = intent.getDataString();
if (Intents.Scan.ACTION.equals(action)) {
// Scan the formats the intent requested, and return the result to the calling activity.
source = IntentSource.NATIVE_APP_INTENT;
decodeFormats = DecodeFormatManager.parseDecodeFormats(intent);
decodeHints = DecodeHintManager.parseDecodeHints(intent);
if (intent.hasExtra(Intents.Scan.WIDTH) && intent.hasExtra(Intents.Scan.HEIGHT)) {
int width = intent.getIntExtra(Intents.Scan.WIDTH, 0);
int height = intent.getIntExtra(Intents.Scan.HEIGHT, 0);
if (width > 0 && height > 0) {
cameraManager.setManualFramingRect(width, height);
}
}
String customPromptMessage = intent.getStringExtra(Intents.Scan.PROMPT_MESSAGE);
if (customPromptMessage != null) {
statusView.setText(customPromptMessage);
}
} else if (dataString != null &&
dataString.contains("http://www.google") &&
dataString.contains("/m/products/scan")) {
// Scan only products and send the result to mobile Product Search.
source = IntentSource.PRODUCT_SEARCH_LINK;
sourceUrl = dataString;
decodeFormats = DecodeFormatManager.PRODUCT_FORMATS;
} else if (isZXingURL(dataString)) {
// Scan formats requested in query string (all formats if none specified).
// If a return URL is specified, send the results there. Otherwise, handle it ourselves.
source = IntentSource.ZXING_LINK;
sourceUrl = dataString;
Uri inputUri = Uri.parse(dataString);
scanFromWebPageManager = new ScanFromWebPageManager(inputUri);
decodeFormats = DecodeFormatManager.parseDecodeFormats(inputUri);
// Allow a sub-set of the hints to be specified by the caller.
decodeHints = DecodeHintManager.parseDecodeHints(inputUri);
}
characterSet = intent.getStringExtra(Intents.Scan.CHARACTER_SET);
}
}
private static boolean isZXingURL(String dataString) {
if (dataString == null) {
return false;
}
for (String url : ZXING_URLS) {
if (dataString.startsWith(url)) {
return true;
}
}
return false;
}
#Override
protected void onPause() {
if (handler != null) {
handler.quitSynchronously();
handler = null;
}
inactivityTimer.onPause();
ambientLightManager.stop();
cameraManager.closeDriver();
if (!hasSurface) {
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
surfaceHolder.removeCallback(this);
}
super.onPause();
}
#Override
protected void onDestroy() {
inactivityTimer.shutdown();
super.onDestroy();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
if (source == IntentSource.NATIVE_APP_INTENT) {
setResult(RESULT_CANCELED);
finish();
return true;
}
if ((source == IntentSource.NONE || source == IntentSource.ZXING_LINK) && lastResult != null) {
restartPreviewAfterDelay(0L);
return true;
}
break;
case KeyEvent.KEYCODE_FOCUS:
case KeyEvent.KEYCODE_CAMERA:
// Handle these events so they don't launch the Camera app
return true;
// Use volume up/down to turn on light
case KeyEvent.KEYCODE_VOLUME_DOWN:
cameraManager.setTorch(false);
return true;
case KeyEvent.KEYCODE_VOLUME_UP:
cameraManager.setTorch(true);
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.capture, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
switch (item.getItemId()) {
case R.id.menu_share:
intent.setClassName(this, ShareActivity.class.getName());
startActivity(intent);
break;
case R.id.menu_history:
intent.setClassName(this, HistoryActivity.class.getName());
startActivityForResult(intent, HISTORY_REQUEST_CODE);
break;
case R.id.menu_settings:
intent.setClassName(this, PreferencesActivity.class.getName());
startActivity(intent);
break;
case R.id.menu_help:
intent.setClassName(this, HelpActivity.class.getName());
startActivity(intent);
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode == RESULT_OK) {
if (requestCode == HISTORY_REQUEST_CODE) {
int itemNumber = intent.getIntExtra(Intents.History.ITEM_NUMBER, -1);
if (itemNumber >= 0) {
HistoryItem historyItem = historyManager.buildHistoryItem(itemNumber);
decodeOrStoreSavedBitmap(null, historyItem.getResult());
}
}
}
}
private void decodeOrStoreSavedBitmap(Bitmap bitmap, Result result) {
// Bitmap isn't used yet -- will be used soon
if (handler == null) {
savedResultToShow = result;
} else {
if (result != null) {
savedResultToShow = result;
}
if (savedResultToShow != null) {
Message message = Message.obtain(handler, R.id.decode_succeeded, savedResultToShow);
handler.sendMessage(message);
}
savedResultToShow = null;
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (holder == null) {
Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
}
if (!hasSurface) {
hasSurface = true;
initCamera(holder);
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
hasSurface = false;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
/**
* A valid barcode has been found, so give an indication of success and show the results.
*
* #param rawResult The contents of the barcode.
* #param scaleFactor amount by which thumbnail was scaled
* #param barcode A greyscale bitmap of the camera data which was decoded.
*/
public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) {
Intent it = getIntent();
it.putExtra("SCAN_RESULT", rawResult.getText());
it.putExtra("SCAN_FORMAT", rawResult.getBarcodeFormat().toString());
setResult(Activity.RESULT_OK, it);
finish();
inactivityTimer.onActivity();
lastResult = rawResult;
ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(this, rawResult);
boolean fromLiveScan = barcode != null;
if (fromLiveScan) {
historyManager.addHistoryItem(rawResult, resultHandler);
// Then not from history, so beep/vibrate and we have an image to draw on
beepManager.playBeepSoundAndVibrate();
drawResultPoints(barcode, scaleFactor, rawResult);
}
switch (source) {
case NATIVE_APP_INTENT:
case PRODUCT_SEARCH_LINK:
handleDecodeExternally(rawResult, resultHandler, barcode);
break;
case ZXING_LINK:
if (scanFromWebPageManager == null || !scanFromWebPageManager.isScanFromWebPage()) {
handleDecodeInternally(rawResult, resultHandler, barcode);
} else {
handleDecodeExternally(rawResult, resultHandler, barcode);
}
break;
case NONE:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
if (fromLiveScan && prefs.getBoolean(PreferencesActivity.KEY_BULK_MODE, false)) {
Toast.makeText(getApplicationContext(),
getResources().getString(R.string.msg_bulk_mode_scanned) + " (" + rawResult.getText() + ')',
Toast.LENGTH_SHORT).show();
// Wait a moment or else it will scan the same barcode continuously about 3 times
restartPreviewAfterDelay(BULK_MODE_SCAN_DELAY_MS);
} else {
handleDecodeInternally(rawResult, resultHandler, barcode);
}
break;
}
}
/**
* Superimpose a line for 1D or dots for 2D to highlight the key features of the barcode.
*
* #param barcode A bitmap of the captured image.
* #param scaleFactor amount by which thumbnail was scaled
* #param rawResult The decoded results which contains the points to draw.
*/
private void drawResultPoints(Bitmap barcode, float scaleFactor, Result rawResult) {
ResultPoint[] points = rawResult.getResultPoints();
if (points != null && points.length > 0) {
Canvas canvas = new Canvas(barcode);
Paint paint = new Paint();
paint.setColor(getResources().getColor(R.color.result_points));
if (points.length == 2) {
paint.setStrokeWidth(4.0f);
drawLine(canvas, paint, points[0], points[1], scaleFactor);
} else if (points.length == 4 &&
(rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A ||
rawResult.getBarcodeFormat() == BarcodeFormat.EAN_13)) {
// Hacky special case -- draw two lines, for the barcode and metadata
drawLine(canvas, paint, points[0], points[1], scaleFactor);
drawLine(canvas, paint, points[2], points[3], scaleFactor);
} else {
paint.setStrokeWidth(10.0f);
for (ResultPoint point : points) {
if (point != null) {
canvas.drawPoint(scaleFactor * point.getX(), scaleFactor * point.getY(), paint);
}
}
}
}
}
private static void drawLine(Canvas canvas, Paint paint, ResultPoint a, ResultPoint b, float scaleFactor) {
if (a != null && b != null) {
canvas.drawLine(scaleFactor * a.getX(),
scaleFactor * a.getY(),
scaleFactor * b.getX(),
scaleFactor * b.getY(),
paint);
}
}
// Put up our own UI for how to handle the decoded contents.
private void handleDecodeInternally(Result rawResult, ResultHandler resultHandler, Bitmap barcode) {
statusView.setVisibility(View.GONE);
viewfinderView.setVisibility(View.GONE);
resultView.setVisibility(View.VISIBLE);
ImageView barcodeImageView = (ImageView) findViewById(R.id.barcode_image_view);
if (barcode == null) {
barcodeImageView.setImageBitmap(BitmapFactory.decodeResource(getResources(),
R.drawable.launcher_icon));
} else {
barcodeImageView.setImageBitmap(barcode);
}
TextView formatTextView = (TextView) findViewById(R.id.format_text_view);
formatTextView.setText(rawResult.getBarcodeFormat().toString());
TextView typeTextView = (TextView) findViewById(R.id.type_text_view);
typeTextView.setText(resultHandler.getType().toString());
DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
TextView timeTextView = (TextView) findViewById(R.id.time_text_view);
timeTextView.setText(formatter.format(new Date(rawResult.getTimestamp())));
TextView metaTextView = (TextView) findViewById(R.id.meta_text_view);
View metaTextViewLabel = findViewById(R.id.meta_text_view_label);
metaTextView.setVisibility(View.GONE);
metaTextViewLabel.setVisibility(View.GONE);
Map<ResultMetadataType,Object> metadata = rawResult.getResultMetadata();
if (metadata != null) {
StringBuilder metadataText = new StringBuilder(20);
for (Map.Entry<ResultMetadataType,Object> entry : metadata.entrySet()) {
if (DISPLAYABLE_METADATA_TYPES.contains(entry.getKey())) {
metadataText.append(entry.getValue()).append('\n');
}
}
if (metadataText.length() > 0) {
metadataText.setLength(metadataText.length() - 1);
metaTextView.setText(metadataText);
metaTextView.setVisibility(View.VISIBLE);
metaTextViewLabel.setVisibility(View.VISIBLE);
}
}
TextView contentsTextView = (TextView) findViewById(R.id.contents_text_view);
CharSequence displayContents = resultHandler.getDisplayContents();
contentsTextView.setText(displayContents);
// Crudely scale betweeen 22 and 32 -- bigger font for shorter text
int scaledSize = Math.max(22, 32 - displayContents.length() / 4);
contentsTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, scaledSize);
TextView supplementTextView = (TextView) findViewById(R.id.contents_supplement_text_view);
supplementTextView.setText("");
supplementTextView.setOnClickListener(null);
if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
PreferencesActivity.KEY_SUPPLEMENTAL, true)) {
SupplementalInfoRetriever.maybeInvokeRetrieval(supplementTextView,
resultHandler.getResult(),
historyManager,
this);
}
int buttonCount = resultHandler.getButtonCount();
ViewGroup buttonView = (ViewGroup) findViewById(R.id.result_button_view);
buttonView.requestFocus();
for (int x = 0; x < ResultHandler.MAX_BUTTON_COUNT; x++) {
TextView button = (TextView) buttonView.getChildAt(x);
if (x < buttonCount) {
button.setVisibility(View.VISIBLE);
button.setText(resultHandler.getButtonText(x));
button.setOnClickListener(new ResultButtonListener(resultHandler, x));
} else {
button.setVisibility(View.GONE);
}
}
if (copyToClipboard && !resultHandler.areContentsSecure()) {
ClipboardInterface.setText(displayContents, this);
}
}
// Briefly show the contents of the barcode, then handle the result outside Barcode Scanner.
private void handleDecodeExternally(Result rawResult, ResultHandler resultHandler, Bitmap barcode) {
if (barcode != null) {
viewfinderView.drawResultBitmap(barcode);
}
long resultDurationMS;
if (getIntent() == null) {
resultDurationMS = DEFAULT_INTENT_RESULT_DURATION_MS;
} else {
resultDurationMS = getIntent().getLongExtra(Intents.Scan.RESULT_DISPLAY_DURATION_MS,
DEFAULT_INTENT_RESULT_DURATION_MS);
}
if (resultDurationMS > 0) {
String rawResultString = String.valueOf(rawResult);
if (rawResultString.length() > 32) {
rawResultString = rawResultString.substring(0, 32) + " ...";
}
statusView.setText(getString(resultHandler.getDisplayTitle()) + " : " + rawResultString);
}
if (copyToClipboard && !resultHandler.areContentsSecure()) {
CharSequence text = resultHandler.getDisplayContents();
ClipboardInterface.setText(text, this);
}
if (source == IntentSource.NATIVE_APP_INTENT) {
// Hand back whatever action they requested - this can be changed to Intents.Scan.ACTION when
// the deprecated intent is retired.
Intent intent = new Intent(getIntent().getAction());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.putExtra(Intents.Scan.RESULT, rawResult.toString());
intent.putExtra(Intents.Scan.RESULT_FORMAT, rawResult.getBarcodeFormat().toString());
byte[] rawBytes = rawResult.getRawBytes();
if (rawBytes != null && rawBytes.length > 0) {
intent.putExtra(Intents.Scan.RESULT_BYTES, rawBytes);
}
Map<ResultMetadataType,?> metadata = rawResult.getResultMetadata();
if (metadata != null) {
if (metadata.containsKey(ResultMetadataType.UPC_EAN_EXTENSION)) {
intent.putExtra(Intents.Scan.RESULT_UPC_EAN_EXTENSION,
metadata.get(ResultMetadataType.UPC_EAN_EXTENSION).toString());
}
Number orientation = (Number) metadata.get(ResultMetadataType.ORIENTATION);
if (orientation != null) {
intent.putExtra(Intents.Scan.RESULT_ORIENTATION, orientation.intValue());
}
String ecLevel = (String) metadata.get(ResultMetadataType.ERROR_CORRECTION_LEVEL);
if (ecLevel != null) {
intent.putExtra(Intents.Scan.RESULT_ERROR_CORRECTION_LEVEL, ecLevel);
}
#SuppressWarnings("unchecked")
Iterable<byte[]> byteSegments = (Iterable<byte[]>) metadata.get(ResultMetadataType.BYTE_SEGMENTS);
if (byteSegments != null) {
int i = 0;
for (byte[] byteSegment : byteSegments) {
intent.putExtra(Intents.Scan.RESULT_BYTE_SEGMENTS_PREFIX + i, byteSegment);
i++;
}
}
}
sendReplyMessage(R.id.return_scan_result, intent, resultDurationMS);
} else if (source == IntentSource.PRODUCT_SEARCH_LINK) {
// Reformulate the URL which triggered us into a query, so that the request goes to the same
// TLD as the scan URL.
int end = sourceUrl.lastIndexOf("/scan");
String replyURL = sourceUrl.substring(0, end) + "?q=" + resultHandler.getDisplayContents() + "&source=zxing";
sendReplyMessage(R.id.launch_product_query, replyURL, resultDurationMS);
} else if (source == IntentSource.ZXING_LINK) {
if (scanFromWebPageManager != null && scanFromWebPageManager.isScanFromWebPage()) {
String replyURL = scanFromWebPageManager.buildReplyURL(rawResult, resultHandler);
sendReplyMessage(R.id.launch_product_query, replyURL, resultDurationMS);
}
}
}
private void sendReplyMessage(int id, Object arg, long delayMS) {
if (handler != null) {
Message message = Message.obtain(handler, id, arg);
if (delayMS > 0L) {
handler.sendMessageDelayed(message, delayMS);
} else {
handler.sendMessage(message);
}
}
}
private void initCamera(SurfaceHolder surfaceHolder) {
if (surfaceHolder == null) {
throw new IllegalStateException("No SurfaceHolder provided");
}
if (cameraManager.isOpen()) {
Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
return;
}
try {
cameraManager.openDriver(surfaceHolder);
// Creating the handler starts the preview, which can also throw a RuntimeException.
if (handler == null) {
handler = new CaptureActivityHandler(this, decodeFormats, decodeHints, characterSet, cameraManager);
}
decodeOrStoreSavedBitmap(null, null);
} catch (IOException ioe) {
Log.w(TAG, ioe);
displayFrameworkBugMessageAndExit();
} catch (RuntimeException e) {
// Barcode Scanner has seen crashes in the wild of this variety:
// java.?lang.?RuntimeException: Fail to connect to camera service
Log.w(TAG, "Unexpected error initializing camera", e);
displayFrameworkBugMessageAndExit();
}
}
private void displayFrameworkBugMessageAndExit() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.app_name));
builder.setMessage(getString(R.string.msg_camera_framework_bug));
builder.setPositiveButton(R.string.button_ok, new FinishListener(this));
builder.setOnCancelListener(new FinishListener(this));
builder.show();
}
public void restartPreviewAfterDelay(long delayMS) {
if (handler != null) {
handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
}
resetStatusView();
}
private void resetStatusView() {
resultView.setVisibility(View.GONE);
statusView.setText(R.string.msg_default_status);
statusView.setVisibility(View.VISIBLE);
viewfinderView.setVisibility(View.VISIBLE);
lastResult = null;
}
public void drawViewfinder() {
viewfinderView.drawViewfinder();
}
}
your SplashScreen Java should look like this:
{
Intent mainIntent = new Intent().setClass(SplashScreenActivity.this, com.google.zxing.client.android.CaptureActivity.class);
// use startActivityForResult instead of startActivity
startActivityForResult(mainIntent)
}
but I guess you already solved you problem!
The Requirements: Ensure that itemLookup is only performed if the button has been held for at least 1 second. Stop the button event when the button has been held for 3 seconds, so the recording used for the lookup will not contain unnecessary data.
The Problem: MotionEvent.ACTION_CANCEL is never called even though debugging confirms that TableLayoutForIntercept's onInterceptTouchEvent is being called before MainActivity's OnTouchListener event is called, as expected. Perhaps I am not understanding the purpose of onInterceptTouchEvent? I've looked at other posts about this matter, but all of them are dealing with swipe or drag events, not cancelling a button press. Perhaps this can't be done?
The Code: Only the relevant parts of MainActivity are shown, along with the full TableLayoutForIntercept class, and of course <com.company.myapplication.TableLayoutForIntercept></com.company.myapplication.TableLayoutForIntercept> tags surround my xml layout.
public class MainActivity extends Activity {
//...
DateTime recordingStartedTime;
DateTime recordingEndedTime;
boolean buttonHeldLongEnough = false;
PackageManager pm = getPackageManager();
boolean micPresent = pm.hasSystemFeature(PackageManager.FEATURE_MICROPHONE);
if (micPresent) {
recordBtn.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View recordView, MotionEvent recordEvent) {
switch (recordEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
// Try to record audio
try {
recordingOff.setVisibility(View.INVISIBLE);
recordingOn.setVisibility(View.VISIBLE);
recordingStartedTime = DateTime.now();
constructPrepareStartRecording();
}
catch (Exception ex) {
Log.e(MainActivity.class.getSimpleName(), "An unknown error occurred.");
}
return true;
case MotionEvent.ACTION_UP:
recordingOff.setVisibility(View.VISIBLE);
recordingOn.setVisibility(View.INVISIBLE);
recordingEndedTime = DateTime.now();
Seconds seconds = Seconds.secondsBetween(recordingStartedTime, recordingEndedTime);
int secondsButtonHeld = seconds.getSeconds();
// Button must have been held at least 1 second before running itemLookup
if (secondsButtonHeld > 0 ) {
buttonHeldLongEnough = true;
}
else {
buttonHeldLongEnough = false;
}
// Need to release resources regardless
stopReleaseResetRecording();
if (buttonHeldLongEnough) {
itemLookup();
}
return true;
case MotionEvent.ACTION_CANCEL:
// I think this is the event I have to trigger to halt the button press
boolean codeHasHitCancel = true;
return codeHasHitCancel;
}
return false;
}
});
}
else {
toastTitle = "Unable To Record";
toastMessage = "Device microphone not found.";
toast = new GenericCustomToast();
toast.show(toastTitle, toastMessage, MainActivity.this);
}
//...
}
public class TableLayoutForIntercept extends TableLayout {
public TableLayoutForIntercept (Context context) {
super(context);
}
public TableLayoutForIntercept (Context context, AttributeSet attrs) {
super(context, attrs);
}
private CancelPressTask cancelPressTask = null;
private boolean stopTouchEvent = false;
#Override
public boolean onInterceptTouchEvent (MotionEvent event) {
final int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
stopTouchEvent = false;
cancelPressTask = new CancelPressTask();
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
cancelPressTask.resetCancelPressTimer();
cancelPressTask.stopCancelPressTimer();
return stopTouchEvent;
}
return super.onInterceptTouchEvent(event);
}
#Override
public boolean onTouchEvent (MotionEvent event) {
if (!stopTouchEvent) {
return super.onTouchEvent(event);
}
return true;
}
private class CancelPressTask {
public final long CANCEL_PRESS_TIMEOUT = 3000; // 3 seconds
private Handler cancelPressHandler = new Handler(){
public void handleMessage(Message msg) {
}
};
private Runnable cancelPressCallback = new Runnable() {
#Override
public void run() {
stopTouchEvent = true;
}
};
public void resetCancelPressTimer(){
cancelPressHandler.removeCallbacks(cancelPressCallback);
cancelPressHandler.postDelayed(cancelPressCallback, CANCEL_PRESS_TIMEOUT);
}
public void stopCancelPressTimer(){
cancelPressHandler.removeCallbacks(cancelPressCallback);
}
}
}
I figured out another way to go about this. Instead of trying to trigger an event, I decided to steal it instead! The below code will stop the recording, then do the item look-up after 3 seconds has elapsed, no matter how long the user tries to hold the button down for. The only catch is for recordings that are too short (less than 1 second) it will still take the full 3 seconds to notify the user via toast message. But I'm willing to live with that.
public class Main Activity extends Activity {
DateTime recordingStartedTime;
DateTime recordingEndedTime = null;
boolean buttonHeldLongEnough = false;
LimitRecordingTask limitRecordingTask;
PackageManager pm = getPackageManager();
boolean micPresent = pm.hasSystemFeature(PackageManager.FEATURE_MICROPHONE);
if (micPresent) {
recordBtn.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View recordView, MotionEvent recordEvent) {
limitRecordingTask = new LimitRecordingTask();
switch (recordEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
// Try to record audio
try {
recordBtn.setBackgroundColor(Color.DKGRAY);
recordingOff.setVisibility(View.INVISIBLE);
recordingOn.setVisibility(View.VISIBLE);
recordingStartedTime = DateTime.now();
constructPrepareStartRecording();
limitRecordingTask.resetRecordingTimer();
}
catch (Exception ex) {
Log.e(MainActivity.class.getSimpleName(), "An unknown error occurred.");
limitRecordingTask.stopRecordingTimer();
}
return true;
case MotionEvent.ACTION_UP:
// After 3 seconds limitRecordingTask will 'steal' this event
recordBtn.setBackgroundResource(R.drawable.custom_button);
recordingOff.setVisibility(View.VISIBLE);
recordingOn.setVisibility(View.INVISIBLE);
recordingEndedTime = DateTime.now();
Seconds seconds = Seconds.secondsBetween(recordingStartedTime, recordingEndedTime);
int secondsButtonHeld = Math.abs(seconds.getSeconds());
if (secondsButtonHeld > 0 ) {
buttonHeldLongEnough = true;
}
else {
buttonHeldLongEnough = false;
}
return true;
}
return false;
}
});
}
else {
toastTitle = "Unable To Record";
toastMessage = "Device microphone not found.";
toast = new GenericCustomToast();
toast.show(toastTitle, toastMessage, MainActivity.this);
}
private class LimitRecordingTask {
public final long RECORDING_TIMEOUT = 3000; // 3 seconds
private Handler limitRecordingHandler = new Handler(){
public void handleMessage(Message msg) {
}
};
private Runnable limitRecordingCallback = new Runnable() {
#Override
public void run() {
// 'Stolen' MotionEvent.ACTION_UP
recordBtn.setBackgroundResource(R.drawable.custom_button);
recordingOff.setVisibility(View.VISIBLE);
recordingOn.setVisibility(View.INVISIBLE);
if (recordingEndedTime == null) {
recordingEndedTime = DateTime.now();
}
Seconds seconds = Seconds.secondsBetween(recordingStartedTime, recordingEndedTime);
int secondsButtonHeld = Math.abs(seconds.getSeconds());
if (secondsButtonHeld > 0 ) {
buttonHeldLongEnough = true;
}
else {
buttonHeldLongEnough = false;
}
limitRecordingTask.stopRecordingTimer();
stopReleaseResetRecording();
itemLookup();
}
};
public void resetRecordingTimer(){
limitRecordingHandler.removeCallbacks(limitRecordingCallback);
limitRecordingHandler.postDelayed(limitRecordingCallback, RECORDING_TIMEOUT);
}
public void stopRecordingTimer(){
limitRecordingHandler.removeCallbacks(limitRecordingCallback);
}
}
}