I load the Indoor Atlas floorplan image but how can i show my position on that image..
Also this image is static please help.
Code for loading floorplan is below.
public void loadFloorPlanImage(FloorPlan floorPlan)
{
BitmapFactory.Options options = createBitmapOptions(floorPlan);
FutureResult<Bitmap> result = mIndoorAtlas.fetchFloorPlanImage(floorPlan,options);
result.setCallback(new ResultCallback<Bitmap>() {
#Override
public void onResult(final Bitmap result) {
runOnUiThread(new Runnable() {
#Override
public void run() {
ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setImageBitmap(result);
}
});
}
});
}
I got the position time to time i just mark that position on the ImageView my code is..
public void onServiceUpdate(ServiceState state) {
double x1 = state.getMetricPoint().getX();
double y1 = state.getMetricPoint().getY();
float x = (float) x1;
float y = (float) y1;
//Paint paint = new Paint();
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setAntiAlias(true);
paint.setColor(Color.RED);
Bitmap workingBitmap = Bitmap.createBitmap(image);
Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);
// canvas.drawCircle(x, y, 100, paint);
canvas.drawCircle(50, 50, 10, paint);
imageView.setAdjustViewBounds(true);
imageView.setImageBitmap(image);
}
But it does not work. Please help Thanks
import java.io.IOException;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import com.indooratlas.android.CalibrationState;
import com.indooratlas.android.FloorPlan;
import com.indooratlas.android.FutureResult;
import com.indooratlas.android.IndoorAtlas;
import com.indooratlas.android.IndoorAtlasException;
import com.indooratlas.android.IndoorAtlasFactory;
import com.indooratlas.android.IndoorAtlasListener;
import com.indooratlas.android.ResultCallback;
import com.indooratlas.android.ServiceState;
/**
* <p>
* Activity to demonstrate basic use of IndoorAtlas SDK. If there are no public
* maps around your location, you can create a map of your own and upload it to
* IndoorAtlas servers. Read more on how to do this from:
* http://developer.indooratlas.com.
* </p>
* <p/>
* <p>
* To run this demo, you will also need your applications API key/secret and
* identifiers for the floor plan from http://developer.indooratlas.com.
* </p>
* <p/>
*/
public class MainActivity extends Activity implements IndoorAtlasListener {
private static final String TAG = "MainActivity";
// private ListView mLogView;
// private LogAdapter mLogAdapter;
private IndoorAtlas mIndoorAtlas;
private boolean mIsPositioning;
private StringBuilder mSharedBuilder = new StringBuilder();
private String apiKey = "YOU API KEY";
private String apiSecret = "YOUR SECRET KEY";
private String floorPlanId = "CUSTOM FLOOR PLAN ID";
private String venueId = "CUSTOM VENUE ID";
private String floorId = "CUSTOM FLOOR ID";
private FloorPlan mFloorPlan;
private ImageView imageView1;
private Bitmap bitmap;
private Bitmap copy;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_layout);
imageView1 = (ImageView) findViewById(R.id.imageView1);
// mLogView = (ListView) findViewById(R.id.list);
// mLogAdapter = new LogAdapter(this);
// mLogView.setAdapter(mLogAdapter);
initIndoorAtlas();
}
#Override
protected void onDestroy() {
super.onDestroy();
tearDown();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_clear_log:
// mLogAdapter.clear();
return true;
case R.id.action_toggle_positioning:
togglePositioning();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void tearDown() {
if (mIndoorAtlas != null) {
mIndoorAtlas.tearDown();
}
}
private void stopPositioning() {
mIsPositioning = false;
if (mIndoorAtlas != null) {
log("Stop positioning");
mIndoorAtlas.stopPositioning();
}
}
private void startPositioning() {
if (mIndoorAtlas != null) {
log(String
.format("startPositioning, venueId: %s, floorId: %s, floorPlanId: %s",
venueId, floorId, floorPlanId));
try {
mIndoorAtlas.startPositioning(venueId, floorId, floorPlanId);
mIsPositioning = true;
} catch (IndoorAtlasException e) {
log("startPositioning failed: " + e);
}
} else {
log("calibration not ready, cannot start positioning");
}
}
private void togglePositioning() {
if (mIsPositioning) {
stopPositioning();
} else {
startPositioning();
}
}
private void initIndoorAtlas() {
try {
log("Connecting with IndoorAtlas, apiKey: " + apiKey);
// obtain instance to positioning service, note that calibrating
// might begin instantly
mIndoorAtlas = IndoorAtlasFactory.createIndoorAtlas(
getApplicationContext(), this, // IndoorAtlasListener
apiKey, apiSecret);
log("IndoorAtlas instance created");
FutureResult<FloorPlan> result = mIndoorAtlas
.fetchFloorPlan(floorPlanId);
result.setCallback(new ResultCallback<FloorPlan>() {
#Override
public void onResult(final FloorPlan result) {
mFloorPlan = result;
loadFloorPlanImage(result);
}
#Override
public void onApplicationError(IndoorAtlasException arg0) {
// TODO Auto-generated method stub
}
#Override
public void onSystemError(IOException arg0) {
// TODO Auto-generated method stub
}
// handle error conditions too
});
try {
Log.d("abcd", "helo14");
mIndoorAtlas.startPositioning(venueId, floorId, floorPlanId);
Log.d("abcd", "helo1");
} catch (IndoorAtlasException e) {
// TODO Auto-generated catch block
Log.d("abcd", "helo");
e.printStackTrace();
}
togglePositioning();
} catch (IndoorAtlasException ex) {
Log.e("IndoorAtlas", "init failed", ex);
log("init IndoorAtlas failed, " + ex.toString());
}
}
private void updateImageViewInUiThread(final Bitmap result) {
runOnUiThread(new Runnable() {
#Override
public void run() {
bitmap = result;
imageView1.setImageBitmap(result);
}
});
}
void loadFloorPlanImage(FloorPlan floorPlan) {
BitmapFactory.Options options = createBitmapOptions(floorPlan);
FutureResult<Bitmap> result = mIndoorAtlas.fetchFloorPlanImage(
floorPlan, options);
result.setCallback(new ResultCallback<Bitmap>() {
#Override
public void onResult(final Bitmap result) {
// now you have floor plan bitmap, do something with it
updateImageViewInUiThread(result);
}
#Override
public void onApplicationError(IndoorAtlasException arg0) {
// TODO Auto-generated method stub
}
#Override
public void onSystemError(IOException arg0) {
// TODO Auto-generated method stub
}
// handle error conditions too
});
}
private void log(final String msg) {
Log.d(TAG, msg);
runOnUiThread(new Runnable() {
#Override
public void run() {
// mLogAdapter.add(msg);
// mLogAdapter.notifyDataSetChanged();
}
});
}
/* IndoorAtlasListener interface */
/**
* This is where you will handle location updates.
*/
#Override
public void onServiceUpdate(ServiceState state) {
Log.d("abcd", "testttt");
final Bitmap icon = BitmapFactory.decodeResource(
getApplicationContext().getResources(), R.drawable.loc_img);
// TODO Auto-generated method stub
final int i = state.getImagePoint().getI();
final int j = state.getImagePoint().getJ();
Log.d("abcd", "" + i + " " + j);
runOnUiThread(new Runnable() {
#Override
public void run() {
if (bitmap != null) {
Bitmap copy2 = bitmap.copy(bitmap.getConfig(), true);
Canvas canvas = new Canvas(copy2);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(icon, i, j, paint);
imageView1.setImageBitmap(copy2);
}
}
});
mSharedBuilder.setLength(0);
mSharedBuilder.append("Location: ").append("\n\troundtrip : ")
.append(state.getRoundtrip()).append("ms").append("\n\tlat : ")
.append(state.getGeoPoint().getLatitude()).append("\n\tlon : ")
.append(state.getGeoPoint().getLongitude())
.append("\n\tX [meter] : ")
.append(state.getMetricPoint().getX())
.append("\n\tY [meter] : ")
.append(state.getMetricPoint().getY())
.append("\n\tI [pixel] : ")
.append(state.getImagePoint().getI())
.append("\n\tJ [pixel] : ")
.append(state.getImagePoint().getJ()).append("\n\theading : ")
.append(state.getHeadingDegrees()).append("\n\tuncertainty: ")
.append(state.getUncertainty());
log(mSharedBuilder.toString());
}
private BitmapFactory.Options createBitmapOptions(FloorPlan floorPlan) {
BitmapFactory.Options options = null;
int reqWidth = 2048;
int reqHeight = 2048;
final int width = (int) floorPlan.dimensions[0];
final int height = (int) floorPlan.dimensions[1];
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
if (options != null) {
options.inSampleSize = inSampleSize;
}
return options;
}
private Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(),
bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, new Matrix(), null);
canvas.drawBitmap(bmp2, new Matrix(), null);
return bmOverlay;
}
#Override
public void onServiceFailure(int errorCode, String reason) {
log("onServiceFailure: reason : " + reason);
}
#Override
public void onServiceInitializing() {
log("onServiceInitializing");
}
#Override
public void onServiceInitialized() {
log("onServiceInitialized");
}
#Override
public void onInitializationFailed(final String reason) {
log("onInitializationFailed: " + reason);
}
#Override
public void onServiceStopped() {
log("onServiceStopped");
}
#Override
public void onCalibrationStatus(CalibrationState calibrationState) {
log("onCalibrationStatus, percentage: "
+ calibrationState.getPercentage());
}
/**
* Notification that calibration has reached level of quality that provides
* best possible positioning accuracy.
*/
#Override
public void onCalibrationReady() {
log("onCalibrationReady");
}
#Override
public void onNetworkChangeComplete(boolean success) {
}
/**
* #deprecated this callback is deprecated as of version 1.4
*/
#Override
public void onCalibrationInvalid() {
}
/**
* #deprecated this callback is deprecated as of version 1.4
*/
#Override
public void onCalibrationFailed(String reason) {
}
}
This code may help you.. And refer this link
Related
I am trying to make an app to detect face using Face API from Azure's tutorial. When I try to run the app, I get an Error:
java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/http/impl/client/DefaultHttpClient;
at com.microsoft.projectoxford.face.rest.WebServiceRequest.(WebServiceRequest.java:67)
at com.microsoft.projectoxford.face.FaceServiceRestClient.(FaceServiceRestClient.java:99)
at com.contoso.facetutorial.MainActivity.(MainActivity.java:28)
Here is my code:
MainActivity.java
package com.contoso.facetutorial;
// <snippet_imports>
import java.io.*;
import java.lang.Object.*;
import android.app.*;
import android.content.*;
import android.net.*;
import android.os.*;
import android.view.*;
import android.graphics.*;
import android.widget.*;
import android.provider.*;
// </snippet_imports>
// <snippet_face_imports>
import com.microsoft.projectoxford.face.*;
import com.microsoft.projectoxford.face.contract.*;
// </snippet_face_imports>
public class MainActivity extends Activity {
// <snippet_mainactivity_fields>
// Add your Face endpoint to your environment variables.
private final String apiEndpoint = "https://ceranfaceapi.cognitiveservices.azure.com/";
// Add your Face subscription key to your environment variables.
private final String subscriptionKey = "xxxx";
private final FaceServiceClient faceServiceClient =
new FaceServiceRestClient(apiEndpoint, subscriptionKey);
private final int PICK_IMAGE = 1;
private ProgressDialog detectionProgressDialog;
// </snippet_mainactivity_fields>
// <snippet_mainactivity_methods>
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1 = findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(
intent, "Select Picture"), PICK_IMAGE);
}
});
detectionProgressDialog = new ProgressDialog(this);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE && resultCode == RESULT_OK &&
data != null && data.getData() != null) {
Uri uri = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(
getContentResolver(), uri);
ImageView imageView = findViewById(R.id.imageView1);
imageView.setImageBitmap(bitmap);
// Comment out for tutorial
detectAndFrame(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
// </snippet_mainactivity_methods>
}
// <snippet_detection_methods>
// Detect faces by uploading a face image.
// Frame faces after detection.
private void detectAndFrame(final Bitmap imageBitmap) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
ByteArrayInputStream inputStream =
new ByteArrayInputStream(outputStream.toByteArray());
AsyncTask<InputStream, String, Face[]> detectTask =
new AsyncTask<InputStream, String, Face[]>() {
String exceptionMessage = "";
#Override
protected Face[] doInBackground(InputStream... params) {
try {
publishProgress("Detecting...");
Face[] result = faceServiceClient.detect(
params[0],
true, // returnFaceId
false, // returnFaceLandmarks
null // returnFaceAttributes:
/* new FaceServiceClient.FaceAttributeType[] {
FaceServiceClient.FaceAttributeType.Age,
FaceServiceClient.FaceAttributeType.Gender }
*/
);
if (result == null){
publishProgress(
"Detection Finished. Nothing detected");
return null;
}
publishProgress(String.format(
"Detection Finished. %d face(s) detected",
result.length));
return result;
} catch (Exception e) {
exceptionMessage = String.format(
"Detection failed: %s", e.getMessage());
return null;
}
}
#Override
protected void onPreExecute() {
//TODO: show progress dialog
detectionProgressDialog.show();
}
#Override
protected void onProgressUpdate(String... progress) {
//TODO: update progress
detectionProgressDialog.setMessage(progress[0]);
}
#Override
protected void onPostExecute(Face[] result) {
//TODO: update face frames
detectionProgressDialog.dismiss();
if(!exceptionMessage.equals("")){
showError(exceptionMessage);
}
if (result == null) return;
ImageView imageView = findViewById(R.id.imageView1);
imageView.setImageBitmap(
drawFaceRectanglesOnBitmap(imageBitmap, result));
imageBitmap.recycle();
}
};
detectTask.execute(inputStream);
}
private void showError(String message) {
new AlertDialog.Builder(this)
.setTitle("Error")
.setMessage(message)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}})
.create().show();
}
// </snippet_detection_methods>
// <snippet_drawrectangles>
private static Bitmap drawFaceRectanglesOnBitmap(
Bitmap originalBitmap, Face[] faces) {
Bitmap bitmap = originalBitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.RED);
paint.setStrokeWidth(10);
if (faces != null) {
for (Face face : faces) {
FaceRectangle faceRectangle = face.faceRectangle;
canvas.drawRect(
faceRectangle.left,
faceRectangle.top,
faceRectangle.left + faceRectangle.width,
faceRectangle.top + faceRectangle.height,
paint);
}
}
return bitmap;
}
// </snippet_drawrectangles>
}
To continue using the Apache HTTP client, apps that target Android 9 and above can add the following to their AndroidManifest.xml:
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
I have this service which send my location to server and get some data from it.
package com.speed00.service;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.widget.Toast;
import com.google.gson.Gson;
import com.speed00.R;
import com.speed00.constant.AppConstant;
import com.speed00.helper.FunctionHelper;
import com.speed00.model.achivment.StepHelper;
import com.speed00.model.ride.RideResultResponse;
import com.speed00.model.ride.UpdateLocationData;
import com.speed00.model.ride.UpdateLocationResponse;
import com.speed00.prefrences.MyPreferences;
import com.speed00.prefrences.MySharedPreference;
import com.speed00.retrofit.ApiUtils;
import com.speed00.stepdetucter.StepDetector;
import com.speed00.stepdetucter.StepListener;
import com.speed00.ui.activity.HomeActivity;
import com.speed00.utils.Logger;
import com.speed00.utils.MySensorEventListener;
import com.speed00.utils.NetworkConnection;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MyService extends Service implements StepListener, SensorEventListener {
// constant
// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
private Timer mTimer = null;
private Double locationRange = 1.0;
private String oldDegree;
private boolean isServiceRunning;
private int numSteps = 0;
private final int FINAL_STEP = 15;
private SensorManager sensorManager;
private Sensor accel;
String speed_received = "0";
private boolean pedoMetterHasStarted = false;
String pLatitude;
String pLongitude;
private SensorEventListener eListener;
private Sensor accelerometer, magFieldSensor;
private StepDetector simpleStepDetector;
#Override
public IBinder onBind(Intent intent) {
return null;
}
private BroadcastReceiver message = new BroadcastReceiver() {
#Override
public void onReceive(Context context, final Intent intent) {
// TODO Auto-generated method stub
new Handler().post(new Runnable() {
#Override
public void run() {
speed_received = intent.getStringExtra("current speed");
Logger.e("speed__recv" + speed_received);
if (speed_received != null) {
// setSpeedValue(speed_received);//this method is calling to set speed.
//This method is calling to validate Timer For Ride
if (speed_received.equalsIgnoreCase("0")) {
if (!pedoMetterHasStarted) {
numSteps = 0;
statPedoMeter();
}
}
//Calculating distance value
String latitude = MySharedPreference.getInstance(MyService.this).getLatitude();
String longitude = MySharedPreference.getInstance(MyService.this).getLongitude();
if (TextUtils.isEmpty(pLatitude)) {
pLatitude = latitude;
pLongitude = longitude;
} else {
/*
* if distance is more then 2 km then its calculatiog.
*
* */
Location pLocation = new Location("P");
pLocation.setLongitude(Double.parseDouble(pLatitude));
pLocation.setLongitude(Double.parseDouble(pLongitude));
Location nLocation = new Location("N");
nLocation.setLongitude(Double.parseDouble(latitude));
nLocation.setLongitude(Double.parseDouble(longitude));
Logger.e("distance----" + pLocation.distanceTo(nLocation));
if (pLocation.distanceTo(nLocation) >= 10) {
pLatitude = latitude;
pLongitude = longitude;
}
}
}
}
});
}
};
#Override
public void onCreate() {
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
eListener = new MySensorEventListener(this, sensorManager);//for direction
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magFieldSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
//callback sensor of ui
sensorManager.registerListener(eListener, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(eListener, magFieldSensor, SensorManager.SENSOR_DELAY_NORMAL);
assert sensorManager != null;
accel = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
simpleStepDetector = new StepDetector();
simpleStepDetector.registerListener(this);
Toast.makeText(getApplicationContext(), "Service Started", Toast.LENGTH_SHORT).show();
isServiceRunning = true;
// Toast.makeText(getApplicationContext(), "service started", Toast.LENGTH_SHORT).show();
// cancel if already existed
if (mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
// new Timer().scheduleAtFixedRate(new TimeDisplayTimerTask(), 100, NOTIFY_INTERVAL);
runLoop();
LocalBroadcastManager.getInstance(this).registerReceiver(message,
new IntentFilter("send"));
}
private void runLoop() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
updateDriverLocation();
if (isServiceRunning)
runLoop();
}
}, 1000);
}
/*
*
* This method is calling to update driver location
* */
private void updateDriverLocation() {
//Get all user details data.
String userId = MySharedPreference.getInstance(getApplicationContext()).getDriverId();
String latitudeData = MySharedPreference.getInstance(getApplicationContext()).getLatitude();
String longitudeData = MySharedPreference.getInstance(getApplicationContext()).getLongitude();
String speedData = MySharedPreference.getInstance(getApplicationContext()).getSpeedData();//how to roinf
Logger.e("SERVER " + latitudeData + " " + longitudeData);
Logger.e("SPEED " + speedData);
String directionValue = MySharedPreference.getInstance(getApplicationContext()).getDirectionValue();
String speeding = MySharedPreference.getInstance(getApplicationContext()).getSpeeding();
String language = MyPreferences.newInstance(getApplicationContext()).getLanguage();//send speeding data to bakend.
String directionText = MySharedPreference.getInstance(getApplicationContext()).getDirectionText();
long driveTime = FunctionHelper.getDifference(MySharedPreference.getInstance(getApplicationContext()).getStartTime());
String validateUTurn = validateUTurn();
// Logger.e("update_request--" + request);
ApiUtils.getAPIService().updateDriverLocation(validateUTurn, directionText, speeding, "" + driveTime, language, userId,
AppConstant.START_RIDE, speedData, directionValue, latitudeData, longitudeData).enqueue(new Callback<UpdateLocationResponse>() {
#Override
public void onResponse(Call<UpdateLocationResponse> call, Response<UpdateLocationResponse> response) {
if (response.isSuccessful()) {
UpdateLocationResponse updateLocationResponse = response.body();
if (updateLocationResponse.getErrorCode().equalsIgnoreCase(AppConstant.ERROR_CODE)) {
if (updateLocationResponse.getData().size() > 0) {
UpdateLocationData updateLocationData = updateLocationResponse.getData().get(0);
String eventData = FunctionHelper.validateData(updateLocationData);
broadCastEventData(eventData, updateLocationResponse.getErrorCode());
broadCastResponseData(updateLocationResponse);
}
}
}
}
#Override
public void onFailure(Call<UpdateLocationResponse> call, Throwable t) {
}
});
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
/*
*
*This method is calling to validateUTurn.
*
*
* */
private String validateUTurn() {
String currentDegree = MySharedPreference.getInstance(this).getDirectionValue();
String uTurnStatus = "0";
if (TextUtils.isEmpty(oldDegree)) {
oldDegree = currentDegree;
uTurnStatus = "0";
return uTurnStatus;
} else {
if (oldDegree == "0.0") {
oldDegree = currentDegree;
}
if (Float.parseFloat(oldDegree) <= Float.parseFloat(currentDegree)) {
uTurnStatus = "1";
} else {
uTurnStatus = "0";
}
if (Float.parseFloat(oldDegree) == 360 || Float.parseFloat(oldDegree) > 270) {
if (Float.parseFloat(currentDegree) > 0 && Float.parseFloat(oldDegree) <= 90) {
uTurnStatus = "1";
}
}
oldDegree = currentDegree;
return uTurnStatus;
}
}
public synchronized void broadCastEventData(String eventData, String errorCode) {
Intent intent = new Intent("event_broad_cast");
intent.putExtra("data", eventData);
intent.putExtra("error", errorCode);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
/*
* This method is calling to broadcast event data
* */
/*
* This method is calling to broadcast event data
* */
public synchronized void broadCastResponseData(UpdateLocationResponse updateLocationData) {
Intent intent = new Intent("location_update");
Bundle args = new Bundle();
args.putSerializable("data", (Serializable) updateLocationData);
intent.putExtra("myvalue", args);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
#Override
public void onDestroy() {
super.onDestroy();
isServiceRunning = false;
LocalBroadcastManager.getInstance(this).unregisterReceiver(message);
// stopPedoMeter();
}
#Override
public void step(long timeNs) {
if (numSteps < 16)
Toast.makeText(this, "" + numSteps, Toast.LENGTH_SHORT).show();
saveStep();
if (calculateSteps()) {
stopRideAfter25step();
stopPedoMeter();//this method is calling to stop ResultActivity
} else if (Double.parseDouble(MySharedPreference.getInstance(this).getSpeedData()) > 10) {
MySharedPreference.getInstance(this).setSteps(new ArrayList<StepHelper>());
numSteps = 0;
} else {
Logger.e("stepsss " + numSteps);
numSteps = numSteps + 1;
}
}
private void stopRideAfter25step() {
MySharedPreference.getInstance(this).setSteps(new ArrayList<StepHelper>());
String speed = MySharedPreference.getInstance(this).getSpeedData();
String direction = MySharedPreference.getInstance(this).getDirectionValue();
String latitude = MySharedPreference.getInstance(this).getLatitude();
String longitude = MySharedPreference.getInstance(this).getLongitude();
String driverId = MySharedPreference.getInstance(this).getDriverId();
String language = MyPreferences.newInstance(this).getLanguage();
String speeding = MySharedPreference.getInstance(this).getSpeeding();
long driveTime = FunctionHelper.getDifference(MySharedPreference.getInstance(this).getStartTime());
//validate internet connection
if (NetworkConnection.isConnection(this)) {
stopRide("" + driveTime, language, speeding, driverId, latitude, longitude, AppConstant.STOP_RIDE, speed, direction);
} else {
Toast.makeText(this, getString(R.string.valid_please_check_network_connection), Toast.LENGTH_LONG).show();
}
}
public void stopRide(final String driveTime, final String languageKey, final String speedLimit, final String driverId, final String latitude, final String longitude, String rideStatus, final String speed, final String direction) {
String[] param = {driveTime, languageKey, speedLimit, driverId, speed, direction, latitude, longitude};
new stopLoc(this).execute(param);
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
simpleStepDetector.updateAccel(event.timestamp, event.values[0], event.values[1], event.values[2]);
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
private static class stopLoc extends AsyncTask<String[], Void, Void> {
Context mContext;
public stopLoc(Context mContext) {
this.mContext = mContext;
}
#Override
protected Void doInBackground(String[]... strings) {
Logger.e("stepsss stopingggg");
String driveTime = strings[0][0];
String languageKey = strings[0][1];
String speedLimit = strings[0][2];
String driverId = strings[0][3];
String speed = strings[0][4];
String direction = strings[0][5];
String latitude = strings[0][6];
String longitude = strings[0][7];
ApiUtils.getAPIService().stopTrip(driveTime, languageKey, speedLimit, driverId, AppConstant.STOP_RIDE, speed, direction, latitude, longitude).enqueue(new Callback<RideResultResponse>() {
#Override
public void onResponse(Call<RideResultResponse> call, Response<RideResultResponse> response) {
Logger.e("response----" + new Gson().toJson(response.body()));
if (response.isSuccessful()) {
String errorCode = response.body().getErrorCode();
if (errorCode.equalsIgnoreCase(AppConstant.ERROR_CODE)) {
tripSuccessData(response.body(), mContext);
} else {
Toast.makeText(mContext, "" + mContext.getString(R.string.text_some_erroroccurs), Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onFailure(Call<RideResultResponse> call, Throwable t) {
Toast.makeText(mContext, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
return null;
}
}
public static void tripSuccessData(Object data, Context context) {
RideResultResponse resultResponse = (RideResultResponse) data;
if (resultResponse.getErrorCode().equalsIgnoreCase(AppConstant.ERROR_CODE)) {
FunctionHelper.enableUserIntraction();
HomeActivity.bSpeedStatus = false;
Intent intent = new Intent("trip_ended");
intent.putExtra("trip_info", resultResponse.getData().get(0));
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
((MyService) context).stopSelf();
} else {
Toast.makeText(context, resultResponse.getErrorMsg(), Toast.LENGTH_SHORT).show();
}
}
private boolean calculateSteps() {
ArrayList<StepHelper> arrayList = MySharedPreference.getInstance(this).getSteps();
ArrayList<StepHelper> newList = new ArrayList<>();
for (int i = 0; i < arrayList.size(); i++) {
long seconds = FunctionHelper.getDifference(arrayList.get(i).getTime());
if ((int) seconds < 180) {
newList.add(arrayList.get(i));
}
}
if (numSteps - newList.get(0).getSteps() >= FINAL_STEP) {
return true;
} else {
MySharedPreference.getInstance(this).setSteps(newList);
return false;
}
}
private void saveStep() {
ArrayList<StepHelper> arrayList = MySharedPreference.getInstance(this).getSteps();
if (arrayList == null) {
arrayList = new ArrayList<>();
}
arrayList.add(new StepHelper(FunctionHelper.getCurrentDateWitTime(), numSteps));
MySharedPreference.getInstance(this).setSteps(arrayList);
}
private void statPedoMeter() {
// Toast.makeText(this, "start count", Toast.LENGTH_SHORT).show();
pedoMetterHasStarted = true;
MySharedPreference.getInstance(this).setStartPedoMeterTime(FunctionHelper.getCurrentDateWitTime());//store current time
if (sensorManager != null)
sensorManager.registerListener(this, accel, SensorManager.SENSOR_DELAY_NORMAL);
}
/*
* This method is calling to stop pedo meter
*
* */
private void stopPedoMeter() {
numSteps = 0;
pedoMetterHasStarted = false;
sensorManager.unregisterListener(this, accelerometer);
sensorManager.unregisterListener(this, accel);
sensorManager.unregisterListener(this, magFieldSensor);
sensorManager = null;
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
Logger.e("MyService --- " + "isRuning");
if (HomeActivity.bSpeedStatus) {
updateDriverLocation();
}
}
});
}
}
}
My app starts and use only 170 MB , but after starting this service , it becomes 220 MB and after finishing it, it still 220 and if i open it again , ram become 240 and if i finish it still 240 and if i open it again it become 260 and so on until app crash
what's the wrong in the service ?
i make sure that it's stopped but don't know why ram not reduced after this service is finished
Try this approache, don't put the stopSelf() inside a static method. Instead, you should call startService again and add an action to the Intent.
So this is how an example actionable service should look like:
public class ExampleService
extends Service {
public static final String START_SERVICE_ACTION = "com.example.action.START_SERVICE";
public static final String STOP_SERVICE_ACTION = "com.example.action.STOP_SERVICE";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String intentAction = intent.getAction();
switch (intentAction) {
case START_SERVICE_ACTION:
//
break;
case STOP_SERVICE_ACTION:
stopSelf();
break;
}
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
// Used only in case if services are bound (Bound Services).
return null;
}
}
Interact with the Service from somewhere:
Start with it like this:
Intent service = new Intent(context, ExampleService.class);
service.setAction(NotificationService.START_SERVICE_ACTION);
startService(service);
Stop it like this:
Intent service = new Intent(context, ExampleService.class);
service.setAction(NotificationService.STOP_SERVICE_ACTION);
startService(service);
You don't really need to pass the START_SERVICE_ACTION in this example, just added it to better understand the design.
I have use button facebook, but when set size height, it is no success.
Can you help me. It my code :
<com.facebook.login.widget.LoginButton
android:id="#+id/btn_login_facebook"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="10dp"
android:layout_marginTop="20sp"/>
You can setPadding for your facebook Like box.
FacebookLikeBox.class
package com.example.facebook;
import com.example.facebook.FacebookLinkStatProcessor.Result;
import com.example.fblike.R;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.PathShape;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.Button;
public class FacebookLikeBox extends Button {
private static final String LOG_TAG = FacebookLikeBox.class.getSimpleName();
private static final Looper BACKGROUND;
static {
HandlerThread thread = new HandlerThread(FacebookLikeBox.class.getSimpleName(), Process.THREAD_PRIORITY_LOWEST);
thread.start();
BACKGROUND = thread.getLooper();
}
private Handler mHandler;
private FacebookLinkStatProcessor mProcessor;
private String mUrl;
private boolean mAttachedToWindow;
private CalloutPath mPath;
private ShapeDrawable mFill;
private ShapeDrawable mStroke;
private float mCornerRadius;
private int mCalloutMarker;
public void setProcessor(FacebookLinkStatProcessor processor) {
mProcessor = processor;
}
public void setPageUrl(String url) {
String old = mUrl;
mUrl = url;
if (old == null && url != null || old != null && !old.equals(url)) {
onUrlChanged(old, url);
}
}
#SuppressLint("NewApi")
#Override
public boolean isAttachedToWindow() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return mAttachedToWindow;
} else {
return super.isAttachedToWindow();
}
}
public FacebookLikeBox(Context context) {
super(context);
init(null);
}
public FacebookLikeBox(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public FacebookLikeBox(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
private void init(AttributeSet attrs) {
mProcessor = new FacebookLinkStatProcessor();
mHandler = new Handler(BACKGROUND, new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
processUrl((String) msg.obj);
return true;
}
});
if (attrs == null) {
return;
}
Context c = getContext();
if (c == null) {
return;
}
TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.FacebookLikeBox);
if (a == null) {
return;
}
Resources r = getResources();
if (r == null) {
return;
}
try {
mPath = new CalloutPath();
mFill = new ShapeDrawable();
mFill.getPaint().setStyle(Paint.Style.FILL);
mFill.getPaint().setColor(a.getColor(R.styleable.FacebookLikeBox_boxFillColor, r.getColor(R.color.com_shamanland_facebook_like_box_background_color)));
mStroke = new ShapeDrawable();
mStroke.getPaint().setStyle(Paint.Style.STROKE);
mStroke.getPaint().setColor(a.getColor(R.styleable.FacebookLikeBox_boxStrokeColor, r.getColor(R.color.com_shamanland_facebook_like_box_text_color)));
mStroke.getPaint().setAntiAlias(true);
mStroke.getPaint().setStrokeWidth(a.getDimension(R.styleable.FacebookLikeBox_boxStrokeWidth, r.getDimension(R.dimen.com_shamanland_facebook_like_box_stroke_width)));
mCornerRadius = a.getDimension(R.styleable.FacebookLikeBox_boxCornersRadius, r.getDimension(R.dimen.com_shamanland_facebook_like_corners_radius));
mCalloutMarker = a.getInt(R.styleable.FacebookLikeBox_calloutMarker, 0);
initBackground();
} finally {
a.recycle();
}
}
#SuppressLint("NewApi")
#SuppressWarnings("deprecation")
private void initBackground() {
Drawable drawable = new LayerDrawable(new Drawable[]{mFill, mStroke});
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
setBackgroundDrawable(drawable);
} else {
setBackground(drawable);
}
setPadding(5, 5, 5, 5); // you can do your padding.
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mAttachedToWindow = true;
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mAttachedToWindow = false;
}
#Override
protected void onSizeChanged(int w, int h, int oldW, int oldH) {
mPath.build(mCalloutMarker, w, h, mStroke.getPaint().getStrokeWidth(), mCornerRadius);
PathShape shape = new PathShape(mPath, w, h);
mFill.setShape(shape);
mStroke.setShape(shape);
}
protected void onUrlChanged(String oldValue, String newValue) {
setText(R.string.com_shamanland_facebook_like_box_text_default);
if (oldValue != null) {
mHandler.removeMessages(0, oldValue);
}
if (newValue != null) {
Message msg = Message.obtain();
if (msg != null) {
msg.obj = newValue;
mHandler.sendMessage(msg);
}
}
}
/**
* Background thread
*/
protected void processUrl(final String url) {
try {
final Result result = mProcessor.processUrl(url);
post(new Runnable() {
#SuppressLint("NewApi")
#Override
public void run() {
if (isAttachedToWindow()) {
postProcessUrl(url, result);
}
}
});
} catch (Throwable ex) {
ex.printStackTrace();
/*if (LOGGING) {
Log.wtf(LOG_TAG, ex);
}*/
}
}
protected void postProcessUrl(String url, Result result) {
if (url.equals(mUrl)) {
onUrlProcessed(result);
}
}
protected void onUrlProcessed(Result result) {
setText(prettyNumber(result.shares));
}
protected String prettyNumber(long number) {
if (number > 1000000000L) {
return number / 1000000000L + "." + (number % 1000000000L) / 100000000L + "b";
} else if (number > 1000000L) {
return number / 1000000L + "." + (number % 1000000L) / 100000L + "m";
} else if (number > 1000L) {
return number / 1000L + "." + (number % 1000L) / 100L + "k";
} else {
return String.valueOf(number);
}
}
}
I am sending some data to an android application over UDP. Therefore i created the following UDPReceiver-Class:
package com.example.urowatch;
import java.net.*;
import java.nio.ByteBuffer;
import java.io.*;
public class UDPReceiver extends Thread
{
private DatagramSocket m_Socket;
private int m_BufferSize;
private Boolean m_End = false;
private int m_TotalLength;
private int m_Received;
private byte[] m_Buffer;
private byte[] m_Result;
private Boolean m_IsNewResult = false;
private float m_Progress;
private int m_ImageCount = 0;
private int m_FrameErrors = 0;
public UDPReceiver(String name, int port, int bufferSize) throws IOException
{
super(name);
m_Socket = new DatagramSocket(port);
m_BufferSize = bufferSize;
m_Socket.setBroadcast(true);
m_Socket.setReceiveBufferSize(m_BufferSize);
}
public void run()
{
while(!m_End)
{
try
{
byte[] buf = new byte[m_BufferSize];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
m_Socket.receive(packet);
ProcessData(packet);
}
catch (IOException e)
{
if (!m_Socket.isClosed())
e.printStackTrace();
}
}
}
private void ProcessData(DatagramPacket packet)
{
if (packet.getLength() == 4)
{
ByteBuffer bb = ByteBuffer.wrap(packet.getData());
m_TotalLength = bb.getInt();
if (m_Received != 0)
m_FrameErrors++;
m_Received = 0;
m_Buffer = new byte[m_TotalLength];
}
else if (m_Buffer != null && m_Received != m_TotalLength)
{
int length = packet.getLength();
System.arraycopy(packet.getData(), 0, m_Buffer, m_Received, length);
m_Received += length;
m_Progress = 100 * (float)m_Received/(float)m_TotalLength;
if (m_Received == m_TotalLength)
{
m_Result = new byte[m_TotalLength];
System.arraycopy(m_Buffer, 0, m_Result, 0, m_TotalLength);
m_IsNewResult = true;
m_ImageCount++;
m_Received = 0;
}
}
}
public Boolean IsNewResult()
{
return m_IsNewResult;
}
public byte[] GetResult()
{
m_IsNewResult = false;
return m_Result;
}
public float GetProgress()
{
return m_Progress;
}
public float GetRatio()
{
return 100 * (float)m_ImageCount / (float)m_FrameErrors;
}
public void stopServer()
{
m_End = true;
if (m_Socket != null)
m_Socket.close();
}
}
And i am using this class like this:
package com.example.urowatch;
import java.io.IOException;
import java.text.DecimalFormat;
import android.os.*;
import android.app.Activity;
import android.app.AlertDialog;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.support.v4.app.NavUtils;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.os.Build;
public class LiveActivity extends Activity {
private static ImageView m_ImageView1;
private static TextView m_TextView1;
private static DecimalFormat m_DF;
private static Context m_Context;
private UDPReceiver m_Receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live);
// Show the Up button in the action bar.
setupActionBar();
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
m_ImageView1 = (ImageView)findViewById(R.id.imageView1);
m_TextView1 = (TextView)findViewById(R.id.textView1);
m_Context = this;
m_DF = new DecimalFormat("00.00");
}
/**
* Set up the {#link android.app.ActionBar}, if the API is available.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.live, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
private static Handler MyHandler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
if (msg.what == 100)
{
float[] infos = (float[])msg.obj;
m_TextView1.setText("Empfange Bild: " + m_DF.format(infos[0]) + "% (FrameErrors: " + m_DF.format(infos[1]) + "%)");
}
else if (msg.what == 101)
{
byte[] b = (byte[])msg.obj;
m_TextView1.setText("Empfange Bild: 100,00%");
m_ImageView1.setImageBitmap(BitmapFactory.decodeByteArray(b, 0, b.length));
}
else if (msg.what == 102)
{
AlertDialog.Builder b = new AlertDialog.Builder(m_Context);
b.setTitle("Fehler");
b.setMessage("Es ist folgende Exception aufgetreten:\n" + (Exception)msg.obj);
b.setNeutralButton("OK", null);
b.show();
}
}
};
#Override
public void onBackPressed() {
super.onBackPressed();
if (m_Receiver != null)
m_Receiver.stopServer();
finish();
}
#Override
public void onPause()
{
m_Receiver.stopServer();
super.onPause();
}
#Override
protected void onResume()
{
try {
m_Receiver = new UDPReceiver("UDPReceiver", 5678, 1024);
m_Receiver.start();
} catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
AlertDialog.Builder b = new AlertDialog.Builder(this);
b.setTitle("Fehler");
b.setMessage("Es ist folgende Exception aufgetreten:\n" + e1);
b.setNeutralButton("OK", null);
b.show();
}
// Thread thread = new Thread()
// {
// #Override
// public void run()
// {
// while(true)
// {
// try {
//sleep(250);
Toast.makeText(getBaseContext(), "Runing Thread", Toast.LENGTH_SHORT).show();
Update();
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// MyHandler.sendMessage(MyHandler.obtainMessage(102, e));
// }
// }
// }
// };
// thread.start();
super.onResume();
}
public void buttonClick(View v)
{
Update();
}
private void Update()
{
if (m_Receiver != null)
{
if (m_Receiver.IsNewResult())
{
byte[] b = m_Receiver.GetResult();
MyHandler.sendMessage(MyHandler.obtainMessage(101, b));
}
else
{
float[] infos = new float[2];
infos[0] = m_Receiver.GetProgress();
infos[1] = m_Receiver.GetRatio();
MyHandler.sendMessage(MyHandler.obtainMessage(100, infos));
}
}
}
}
As you see i want to check the status of the UDPReceiver-Object (Is there a new complete byte[] ready?) by a thread. To update the GUI, the thread has to send a Message to MyHandler which will update the GUI.
In the moment i have to to click a button to raise the buttonClick-Event. Later on i want to do this in the commented thread-structure.
Now, here's my problem:
I start the Activity and everything works fine. Then i am starting to send ONE packet manually with my UDP-Sender (which works, i validated it with a C#-UDP-Receiver). The first packet get received fine. Then i send the second packet which get received, too. But from now on, my breakpoint at m_Socket.receive(packet); wont get hit anymore!
I have NO idea what this behaviour causes and it is very important for me to make this application work.
Please, if you have ANY Idea or just a guess, please let me know.
I've been working on Android (v2.3) for a couple of weeks now, and I've stumbled upon some problems with the Unimag Card Swiper from IDTECH.
The unit comes with a scarce documentation and the demo app from the SDK implements the firmware update and a few classes for dialogs and such which really offuscate how to achieve basic functionality (added to the few and not so good comments in the code).
I have implemented the interface in a basic activity and tried to detect when the unit is connected or disconnected but it seems the listener catches both events (connection/disconnection) as "disconnect", let alone trying to read a card.
Has anyone worked with this unit on Android and has some clear examples?
By the way, here is my class:
package com.card.swipe;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import IDTech.MSR.uniMag.uniMagReader;
import IDTech.MSR.uniMag.uniMagReaderMsg;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class CardSwipeTestActivity extends Activity implements uniMagReaderMsg {
private uniMagReader myUniMagReader = null;
private TextView etCardData;
private String _strMSRData = null;
private byte[]_MSRData = null;
private String _strStatus = null;
private int _nGetChallengeResult = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// InitializeUI();
InitializeReader();
String strManufacture = myUniMagReader.getInfoManufacture();
String strModel = myUniMagReader.getInfoModel();
String strSDKVerInfo = myUniMagReader.getSDKVersionInfo();
String strOSVerInfo = android.os.Build.VERSION.RELEASE;
etCardData = (TextView)findViewById(R.id.text_view);
etCardData.setText("Phone: "+strManufacture+"\n"+"Model: "+strModel+"\n"+"SDK Ver: "+strSDKVerInfo+"\nOS Version: "+strOSVerInfo);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
if(myUniMagReader!=null)
{
//you should stop swipe card and unregister when the application go to background
myUniMagReader.stopSwipeCard();
// myUniMagReader.unregisterListen();
// myUniMagReader.release();
}
super.onPause();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
// you should register to listen the headset event when the application resumed.
// if(myUniMagReader!=null)
// {
//// myUniMagReader.registerListen();
// if(_bCheckedSaveLogItem==true)
// myUniMagReader.setSaveLogEnable(true);
// else
// myUniMagReader.setSaveLogEnable(false);
// }
// if(itemStartSC!=null)
// itemStartSC.setEnabled(true);
// waitingCommandResult=false;
super.onResume();
}
#Override
protected void onDestroy() {
myUniMagReader.release();
super.onDestroy();
android.os.Process.killProcess(android.os.Process.myPid());
}
//********************************************************************************//
#Override
public boolean getUserGrant(int arg0, String arg1) {
// TODO Auto-generated method stub
return false;
}
#Override
public void onReceiveMsgAutoConfigProgress(int arg0) {
// TODO Auto-generated method stub
}
#Override
public void onReceiveMsgCardData(byte arg0, byte[] arg1) {
// TODO Auto-generated method stub
Log.d("SWIPE", "Card swiped!");
Toast.makeText(getApplicationContext(), "Card swiped!", Toast.LENGTH_SHORT).show();
}
#Override
public void onReceiveMsgCommandResult(int arg0, byte[] arg1) {
// TODO Auto-generated method stub
}
#Override
public void onReceiveMsgConnected() {
Log.d("CONNECTION","Swiper Connected");
Toast.makeText(getApplicationContext(), "Swiper Connected!", Toast.LENGTH_SHORT).show();
}
#Override
public void onReceiveMsgDisconnected() {
Log.d("CONNECTION","Swiper Disconnected");
Toast.makeText(getApplicationContext(), "Swiper Disconnected!", Toast.LENGTH_SHORT).show();
}
#Override
public void onReceiveMsgFailureInfo(int arg0, String arg1) {
// TODO Auto-generated method stub
Log.d("CONNECTION","Swiper Failure");
}
#Override
public void onReceiveMsgSDCardDFailed(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onReceiveMsgTimeout(String arg0) {
Log.d("TIMEOUT","Timed out!");
Toast.makeText(getApplicationContext(), "Timed out!", Toast.LENGTH_SHORT).show();
}
#Override
public void onReceiveMsgToConnect() {
Log.d("CONNECTION","Swiper Powered Up");
Toast.makeText(getApplicationContext(), "Swiper Powered Up", Toast.LENGTH_SHORT).show();
}
#Override
public void onReceiveMsgToSwipeCard() {
Log.d("SWIPE","Ready to swipe!");
Toast.makeText(getApplicationContext(), "Ready to swipe!", Toast.LENGTH_SHORT).show();
}
//********************************************************************************//
private void InitializeReader()
{
if(myUniMagReader==null)
myUniMagReader = new uniMagReader(this,this);
myUniMagReader.setVerboseLoggingEnable(true);
myUniMagReader.registerListen();
//load the XML configuratin file
String fileNameWithPath = getXMLFileFromRaw();
if(!isFileExist(fileNameWithPath)) { fileNameWithPath = null; }
myUniMagReader.setXMLFileNameWithPath(fileNameWithPath);
myUniMagReader.loadingConfigurationXMLFile(true);
myUniMagReader.setTimeoutOfSwipeCard(5);
}
private boolean isFileExist(String path) {
if(path==null)
return false;
File file = new File(path);
if (!file.exists()) {
return false ;
}
return true;
}
private String getXMLFileFromRaw( ){
//the target filename in the application path
String fileNameWithPath = null;
fileNameWithPath = "idt_unimagcfg_default.xml";
try{
InputStream in = getResources().openRawResource(R.raw.idt_unimagcfg_default);
int length = in.available();
byte [] buffer = new byte[length];
in.read(buffer);
in.close();
deleteFile(fileNameWithPath);
FileOutputStream fout = openFileOutput(fileNameWithPath, MODE_PRIVATE);
fout.write(buffer);
fout.close();
// to refer to the application path
File fileDir = this.getFilesDir();
fileNameWithPath = fileDir.getParent() + java.io.File.separator + fileDir.getName();
fileNameWithPath = fileNameWithPath+java.io.File.separator+"idt_unimagcfg_default.xml";
}
catch(Exception e){
e.printStackTrace();
fileNameWithPath = null;
}
return fileNameWithPath;
}
public void swipe(View v)
{
if(myUniMagReader!=null)
{
myUniMagReader.startSwipeCard();
}
if(myUniMagReader.isSwipeCardRunning()==true)
{
Log.d("SWIPE","Swipe Card Running!");
}
}
private String getHexStringFromBytes(byte []data)
{
if(data.length<=0) return null;
StringBuffer hexString = new StringBuffer();
String fix = null;
for (int i = 0; i < data.length; i++) {
fix = Integer.toHexString(0xFF & data[i]);
if(fix.length()==1)
fix = "0"+fix;
hexString.append(fix);
}
fix = null;
fix = hexString.toString();
return fix;
}
public byte[] getBytesFromHexString(String strHexData)
{
if (1==strHexData.length()%2) {
return null;
}
byte[] bytes = new byte[strHexData.length()/2];
for (int i=0;i<strHexData.length()/2;i++) {
bytes[i] = (byte) Integer.parseInt(strHexData.substring(i*2, (i+1)*2) , 16);
}
return bytes;
}
}
(There are some unimplemented methods there as well)
Here's what I used with the UniMag. Using a handler to output the swiped data, and a 'Swipe' button to start the swiping. To improve, one should wait until the card reader reports it is connected / ready to swipe, then enable the button, disable while waiting for swipe, and re-enable after receiving data.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import IDTech.MSR.XMLManager.StructConfigParameters;
import IDTech.MSR.uniMag.uniMagReader;
import IDTech.MSR.uniMag.uniMagReaderMsg;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements uniMagReaderMsg {
private uniMagReader myUniMagReader = null;
private Button btnSwipe;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(myUniMagReader == null) {
myUniMagReader = new uniMagReader(this,this);
myUniMagReader.setSaveLogEnable(false);
myUniMagReader.setXMLFileNameWithPath(null);
myUniMagReader.loadingConfigurationXMLFile(true);
//myUniMagReader.setVerboseLoggingEnable(true);
myUniMagReader.registerListen();
}
btnSwipe = (Button) findViewById(R.id.button1);
btnSwipe.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
myUniMagReader.startSwipeCard();
}
});
}
#Override
public void onDestroy() {
myUniMagReader.stopSwipeCard();
myUniMagReader.unregisterListen();
myUniMagReader.release();
super.onDestroy();
}
#Override
public boolean getUserGrant(int arg0, String arg1) {
Log.d("UniMag", "getUserGrant -- " + arg1);
return true;
}
#Override
public void onReceiveMsgAutoConfigProgress(int arg0) {
// TODO Auto-generated method stub
Log.d("UniMag", "onReceiveMsgAutoConfigProgress");
}
#Override
public void onReceiveMsgCardData(byte arg0, byte[] arg1) {
Log.d("UniMag", "onReceiveMsgCardData");
Log.d("UniMag", "Successful swipe!");
String strData = new String(arg1);
Log.d("UniMag", "SWIPE - " + strData);
if(myUniMagReader.isSwipeCardRunning()) {
myUniMagReader.stopSwipeCard();
}
// Match the data we want.
String pattern = "%B(\\d+)\\^([^\\^]+)\\^(\\d{4})";
Log.d("UniMag", pattern);
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(strData);
String card = "";
String name = "";
String exp = "";
String data = "";
if(m.find()) {
for(int a = 0; a < m.groupCount(); ++a) {
Log.d("UniMag", a + " - "+m.group(a));
}
card = m.group(1);
name = m.group(2);
exp = m.group(3);
data = "Data: " + name + " -- " + card + " -- " + exp;
Log.d("UniMag", data);
Message msg = new Message();
msg.obj = data;
swipeHandler.sendMessage(msg);
}
}
final Handler swipeHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
String text = (String)msg.obj;
TextView dataView = (TextView) findViewById(R.id.text_view);
dataView.setText(text);
}
};
#Override
public void onReceiveMsgCommandResult(int arg0, byte[] arg1) {
Log.d("UniMag", "onReceiveMsgCommandResult");
}
#Override
public void onReceiveMsgConnected() {
Log.d("UniMag", "onReceiveMsgConnected");
Log.d("UniMag", "Card reader is connected.");
}
#Override
public void onReceiveMsgDisconnected() {
Log.d("UniMag", "onReceiveMsgDisconnected");
if(myUniMagReader.isSwipeCardRunning()) {
myUniMagReader.stopSwipeCard();
}
myUniMagReader.release();
}
#Override
public void onReceiveMsgFailureInfo(int arg0, String arg1) {
Log.d("UniMag","onReceiveMsgFailureInfo -- " + arg1);
}
#Override
public void onReceiveMsgSDCardDFailed(String arg0) {
Log.d("UniMag", "onReceiveMsgSDCardDFailed -- " + arg0);
}
#Override
public void onReceiveMsgTimeout(String arg0) {
Log.d("UniMag", "onReceiveMsgTimeout -- " + arg0);
Log.d("UniMag","Timed out!");
}
#Override
public void onReceiveMsgToConnect() {
Log.d("UniMag","Swiper Powered Up");
}
#Override
public void onReceiveMsgToSwipeCard() {
Log.d("UniMag","onReceiveMsgToSwipeCard");
}
#Override
public void onReceiveMsgAutoConfigCompleted(StructConfigParameters arg0) {
Log.d("UniMag", "onReceiveMsgAutoConfigCompleted");
}
}
I found that the 3.8 demo app they ship with the SDK has a bug where it will not connect to an Android gt-p3113 tablet unless you go into settings on the app on the phone and turn off 'Command To Connect'.