I am trying to do a google places tutorial i found on the net.But i am getting NPE in a certain class:
ShowGoogleMap.java
package com.gmap;
import java.util.List;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
public class ShowGoogleMap extends MapActivity {
protected static int updated_lat;
protected static int updated_lng;
// Used to add overlay markers of both type
List<Overlay> listOfOverlays;
private boolean isPotentialLongPress;
ProgressDialog progressDialog;
// adding your own place info
static double addLat = 0;
static double addLng = 0;
static String locType = "cafe";
static String LocName = "OffCourse Golf Hole";
static String detailText;
Button reloadButton;
Button placeDetailsButton;
Button addPlaceButton;
private MapController mapController;
private MapView mapView;
private LocationManager locationManager;
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.showmap);
mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
mapView.setStreetView(true);
//mapView.setSatellite(true);
mapController = mapView.getController();
mapController.setZoom(14); // Zoom 1 is world view
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new GeoUpdateHandler());
reloadButton = (Button)findViewById(R.id.relaod);
placeDetailsButton = (Button)findViewById(R.id.place_details);
addPlaceButton = (Button)findViewById(R.id.add_place);
// set place Button listener here
reloadButton.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
SearchSrv srv = new SearchSrv();
setProgressBarIndeterminateVisibility(true);
srv.execute();
}
});
// set Detail Button listener here
placeDetailsButton.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
if (MyItemizedOverlay.reference == null) {
Toast.makeText(getBaseContext(), "Please select your place marker first!", Toast.LENGTH_SHORT).show();
}else{
DetailSrv srv = new DetailSrv();
setProgressBarIndeterminateVisibility(true);
srv.execute();
}
}
});
// To show an AlertDialog Box
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Please select your location by long pressing")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
// set add place Button listener here
addPlaceButton.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
if (addLat == 0 && addLng == 0){
AlertDialog alert = builder.create();
alert.show();
}
else{
Intent myIntent = new Intent(getBaseContext(), PlaceAdd.class);
startActivityForResult(myIntent, 0);
setProgressBarIndeterminateVisibility(false);
}
}
});
} // end onCreate() method here
private class SearchSrv extends AsyncTask<Void, Void, PlacesList>{
#Override
protected PlacesList doInBackground(Void... params) {
PlacesList pl = null;
try {
// send place search request from here
pl = new PlaceRequest().performSearch();
} catch (Exception e) {
e.printStackTrace();
}
return pl;
}
#Override
protected void onPostExecute(PlacesList result) {
Drawable marker=getResources().getDrawable(R.drawable.places_marker);
int markerWidth = marker.getIntrinsicWidth();
int markerHeight = marker.getIntrinsicHeight();
marker.setBounds(0, markerHeight, markerWidth, 0);
for(int i = 0; i < listOfOverlays.size(); i++){
if (i != 0){
listOfOverlays.remove(i);
}
}
// Here place searched are displayed on google map as Red markers
if (result != null) {
int []lat = new int[PlaceRequest.latList.size()];
int []lng = new int[PlaceRequest.lngList.size()];
MyItemizedOverlay myItemizedOverlay = new MyItemizedOverlay(marker, ShowGoogleMap.this);
listOfOverlays = mapView.getOverlays();
listOfOverlays.add(myItemizedOverlay);
for(int i = 0; i< PlaceRequest.latList.size(); i++) {
lat[i] = (int)(PlaceRequest.latList.get(i) * 1E6);
lng[i] = (int)(PlaceRequest.lngList.get(i) * 1E6);
Log.v("GPS", "My Place Location is: "+ lat[i] + "," + lng[i]);
GeoPoint point = new GeoPoint(lat[i], lng[i]);
myItemizedOverlay.addItem(point, "OffCourse Golf Hole "+i, PlaceRequest.placeReference.get(i).toString());
}
} else{
Toast.makeText(getBaseContext(), "Please Try Again", Toast.LENGTH_SHORT).show();
}
setProgressBarIndeterminateVisibility(false);
}
} // End of class SearchSrv here
private class DetailSrv extends AsyncTask<Void, Void, PlaceDetail>{
#Override
protected PlaceDetail doInBackground(Void... params) {
PlaceDetail pl = null;
try {
// send place search request from here
pl = new PlaceRequest().performDetails(MyItemizedOverlay.reference);
} catch (Exception e) {
e.printStackTrace();
}
return pl;
}
#Override
protected void onPostExecute(PlaceDetail details) {
Log.v(PlaceRequest.LOG_KEY, "Place details JSON format: " + details);
//to display place Details
detailText = "Place Details\n\n";
if (details != null) {
Place place = details.result;
detailText = detailText + "id = " + place.id +"\n";
detailText = detailText + "name = " + place.name +"\n";
detailText = detailText + "reference = " + place.reference +"\n";
detailText = detailText + "types = " + place.types[0]+"\n";
detailText = detailText + "phone_number = " + place.international_phone_number+"\n";
detailText = detailText + "url = " + place.url +"\n";
detailText = detailText + "vicinity = " + place.vicinity +"\n";
detailText = detailText + "website = " + place.website +"\n";
detailText = detailText + "rating = " + place.rating +"\n";
detailText = detailText + "formatted_address = " + place.formatted_address +"\n";
detailText = detailText + "lat = " + place.geometry.location.lat +"\n";
detailText = detailText + "lng = " + place.geometry.location.lng +"\n";
Log.v(PlaceRequest.LOG_KEY, "Details = " + detailText );
}
// To show my My Custom Dialog box: DetailDialog
Intent myIntent = new Intent(getBaseContext(), ShowPlaceDetail.class);
startActivityForResult(myIntent, 0);
setProgressBarIndeterminateVisibility(false);
}
} // End of class SearchSrv here
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
handleLongPress(event);
return super.dispatchTouchEvent(event);
}
// Here detecting user long press to add my own place
private void handleLongPress( final MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// A new touch has been detected
new Thread(new Runnable() {
public void run() {
Looper.prepare();
if (isLongPressDetected()) {
// We have a long press! Perform your action here
GeoPoint p = mapView.getProjection().fromPixels((int) event.getX(), (int) event.getY());
addLat = p.getLatitudeE6() / 1E6;
addLng = p.getLongitudeE6() / 1E6;
Log.v("Long Press", "Location on Touch: " + p.getLatitudeE6() / 1E6+ "," +p.getLongitudeE6() / 1E6);
}
}
}).start();
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (event.getHistorySize() < 1)
return; // First call, no history
// Get difference in position since previous move event
float diffX = event.getX() - event.getHistoricalX(event.getHistorySize() - 1);
float diffY = event.getY() - event.getHistoricalY(event.getHistorySize() - 1);
/* If position has moved substatially, this is not a long press but probably a drag action */
if (Math.abs(diffX) > 0.5f || Math.abs(diffY) > 0.5f) {
isPotentialLongPress = false;
}
} else {
// This motion is something else, and thus not part of a longpress
isPotentialLongPress = false;
}
}
public boolean isLongPressDetected() {
isPotentialLongPress = true;
try {
for (int i = 0; i < 50; i++) {
Thread.sleep(10);
if (!isPotentialLongPress) {
return false;
}
}
return true;
} catch (InterruptedException e) {
return false;
} finally {
isPotentialLongPress = false;
}
}
public class GeoUpdateHandler implements LocationListener {
// To get user current location (latitude, longitude)
public void onLocationChanged(Location location) {
updated_lat = (int) (location.getLatitude() * 1E6);
updated_lng = (int) (location.getLongitude() * 1E6);
Log.v("GPS", "Updated Lat , Updated Lng: "+ updated_lat + "," + updated_lng);
GeoPoint point = new GeoPoint(updated_lat, updated_lng);
mapController.animateTo(point); // mapController.setCenter(point);
listOfOverlays = mapView.getOverlays();
if (listOfOverlays.isEmpty()){
listOfOverlays.add(new MapOverlay(point));
}
else{
// replace it
listOfOverlays.set(0, new MapOverlay(point));
}
mapView.invalidate();
}
// Overlay for for user current location
class MapOverlay extends Overlay {
GeoPoint point = null;
MapOverlay (GeoPoint point){
this.point = point;
}
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
super.draw(canvas, mapView, shadow);
//---translate the GeoPoint to screen pixels---
Point screenPts = new Point();
mapView.getProjection().toPixels(point, screenPts);
//---add the marker---
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.user_marker);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y-33, null); // 33 is height of marker
return true;
}
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
}
LOGCAT:
07-01 14:06:38.187: E/AndroidRuntime(14123): FATAL EXCEPTION: main
07-01 14:06:38.187: E/AndroidRuntime(14123): java.lang.NullPointerException
07-01 14:06:38.187: E/AndroidRuntime(14123): at com.gmap.ShowGoogleMap$SearchSrv.onPostExecute(ShowGoogleMap.java:159)
07-01 14:06:38.187: E/AndroidRuntime(14123): at com.gmap.ShowGoogleMap$SearchSrv.onPostExecute(ShowGoogleMap.java:1)
07-01 14:06:38.187: E/AndroidRuntime(14123): at android.os.AsyncTask.finish(AsyncTask.java:417)
07-01 14:06:38.187: E/AndroidRuntime(14123): at android.os.AsyncTask.access$300(AsyncTask.java:127)
07-01 14:06:38.187: E/AndroidRuntime(14123): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
07-01 14:06:38.187: E/AndroidRuntime(14123): at android.os.Handler.dispatchMessage(Handler.java:99)
07-01 14:06:38.187: E/AndroidRuntime(14123): at android.os.Looper.loop(Looper.java:130)
07-01 14:06:38.187: E/AndroidRuntime(14123): at android.app.ActivityThread.main(ActivityThread.java:3689)
07-01 14:06:38.187: E/AndroidRuntime(14123): at java.lang.reflect.Method.invokeNative(Native Method)
07-01 14:06:38.187: E/AndroidRuntime(14123): at java.lang.reflect.Method.invoke(Method.java:507)
07-01 14:06:38.187: E/AndroidRuntime(14123): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
07-01 14:06:38.187: E/AndroidRuntime(14123): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
07-01 14:06:38.187: E/AndroidRuntime(14123): at dalvik.system.NativeStart.main(Native Method)
Please help..I am new to the google maps and places api.So i dont fully understand the code from the tutorial.
Yo have to initialise your arraylist oh listOfOverlays before you are using it.
Initialize listOfOverlays like this:
List<Overlay> listOfOverlays = new ArrayList<Overlay>();
That will remove NPE.
Related
I'm trying to draw an image using Canvas.rotate and/or Canvas.drawBimtap, although everytime I use it, the image appears in random locations, no matter the X and Y coordinates I set it to. Here is my code, let me know if this is an issue I should report or if there is just an error in my code:
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Paint;
import android.graphics.SurfaceTexture;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
public class Photo_Page extends AppCompatActivity implements SensorEventListener {
#Override
protected void onStart()
{
super.onStart();
GlobalClass application=(GlobalClass) getApplication();
TextView projectnameheader = (TextView) findViewById(R.id.projectnameheader2);
projectnameheader.setText(application.projectnameheader);
TextView projectnameoverlay = (TextView) findViewById(R.id.projectnameoverlay);
projectnameoverlay.setText(application.projectnameheader);
String currentDateTimeString = java.text.DateFormat.getDateTimeInstance().format(new Date());
Button addcodeandnote = (Button) findViewById(R.id.addcodebutton);
EditText entercode2 = (EditText) findViewById(R.id.entercode);
EditText enternote2 = (EditText) findViewById(R.id.enternote);
TextView codedisplay = (TextView) findViewById(R.id.code);
TextView notedisplay = (TextView) findViewById(R.id.note);
Button savecodebutton = (Button) findViewById(R.id.codesavebutton);
TextView dateandtime = (TextView) findViewById(R.id.dateandtime);
dateandtime.setText(currentDateTimeString);
addcodeandnote.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
if (addcodebuttonpressedtimes>=1) {
addcodebuttonpressedtimes=0;
entercode2.setVisibility(View.INVISIBLE);
enternote2.setVisibility(View.INVISIBLE);
savecodebutton.setVisibility(View.INVISIBLE);
}
else{
addcodebuttonpressedtimes +=1;
entercode2.setVisibility(View.VISIBLE);
enternote2.setVisibility(View.VISIBLE);
savecodebutton.setVisibility(View.VISIBLE);
savecodebutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
code=entercode2.getText().toString();
note=enternote2.getText().toString();
codedisplay.setText(code);
notedisplay.setText(note);
Toast.makeText(Photo_Page.this, "Code and Note were saved successfully!", Toast.LENGTH_LONG).show();
entercode2.setVisibility(View.INVISIBLE);
enternote2.setVisibility(View.INVISIBLE);
savecodebutton.setVisibility(View.INVISIBLE);
addcodebuttonpressedtimes=0;
if (code==null) {
codedisplay.setVisibility(View.INVISIBLE);
}
else{
codedisplay.setVisibility(View.VISIBLE);
}
if (note==null) {
notedisplay.setVisibility(View.INVISIBLE);
}
else{
notedisplay.setVisibility(View.VISIBLE);
}
}
});
}
}
});
}
String m_path = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM).getAbsolutePath();
public String directionNESW;
public List gpslist = new ArrayList();
private final static String TAG = MainActivity.class.getSimpleName();
public Calendar c = Calendar.getInstance();
public SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
public SimpleDateFormat sdftime = new SimpleDateFormat("HHmmss");
public String time;
public String date;
boolean laton = false;
boolean longon = false;
boolean alton = false;
public String names = "Address (GPS signal not found)";
public double latitude;
public double longitude;
public double altitude;
public boolean photowithcode = false;
private Button btnCapture;
private TextureView textureView2;
public String addcodebuttonpressed = "false";
public int addcodebuttonpressedtimes = 0;
public String code = "Code (Empty)";
public String note = "Note (Empty)";
public TextView degrees;
public TextView direction;
public ImageView compass;
public SensorManager sensorManager;
public Sensor accelerometerSensor, magnetometerSensor;
public float[] lastAccelerometer = new float[3];
public float[] lastMagnetometer = new float[3];
public float[] rotationMatrix = new float[9];
public float[] orientation = new float[3];
boolean isLastAccelerometerArrayCopied = false;
boolean isLastMagnetometerArrayCopied = false;
long lastUpdatedTime = 0;
float currentDegrees = 0f;
private ImageView compass2;
private float[] mGravity = new float[3];
private float[] mGeomagnetic = new float[3];
private float azimuth = 0f;
private float currectAzimuth = 0f;
private SensorManager mSensorManager;
//Check state orientation of output image
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static{
ORIENTATIONS.append(Surface.ROTATION_0,90);
ORIENTATIONS.append(Surface.ROTATION_90,0);
ORIENTATIONS.append(Surface.ROTATION_180,270);
ORIENTATIONS.append(Surface.ROTATION_270,180);
}
private String cameraId;
private CameraDevice cameraDevice;
private CameraCaptureSession cameraCaptureSessions;
private CaptureRequest.Builder captureRequestBuilder;
private Size imageDimension;
private ImageReader imageReader;
//Save to FILE
private File file;
private static final int REQUEST_CAMERA_PERMISSION = 200;
private boolean mFlashSupported;
private Handler mBackgroundHandler;
private HandlerThread mBackgroundThread;
CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(#NonNull CameraDevice camera) {
cameraDevice = camera;
createCameraPreview();
}
#Override
public void onDisconnected(#NonNull CameraDevice cameraDevice) {
cameraDevice.close();
}
#Override
public void onError(#NonNull CameraDevice cameraDevice, int i) {
cameraDevice.close();
cameraDevice=null;
}
};
private TextView gpsdisplay;
public TextView altitudetext;
private LocationManager locationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo_page);
compass2 = (ImageView)findViewById(R.id.compass);
degrees = (TextView)findViewById(R.id.degree);
direction = (TextView)findViewById(R.id.direction);
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
TextView address = (TextView) findViewById(R.id.address);
gpsdisplay = findViewById(R.id.gpscoords);
altitudetext = findViewById(R.id.altitude);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if(ContextCompat.checkSelfPermission(Photo_Page.this, Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(Photo_Page.this,Manifest.permission.ACCESS_FINE_LOCATION)!=PackageManager.PERMISSION_GRANTED);
{
ActivityCompat.requestPermissions(Photo_Page.this,new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION},69);
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10, 1, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
altitude = location.getAltitude();
if ((alton && laton && longon) == false) {
gpsdisplay.setText(String.format("%.5f", latitude) + ", " + String.format("%.5f", longitude));
laton = true;
longon = true;
altitudetext.setText(String.format("%.2f", altitude) + " Meters");
alton = true;
}
Geocoder geocoder = new Geocoder(Photo_Page.this, Locale.getDefault());
try {
List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
setUpdata(addresses);
} catch (IOException e) {
e.printStackTrace();
}
}
private void setUpdata(List<Address> addresses) {
String add = addresses.get(0).getAddressLine(0);
String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String zip = addresses.get(0).getPostalCode();
names = add;
address.setText(names);
}
});
textureView2 = (TextureView)findViewById(R.id.textureView);
//From Java 1.4 , you can use keyword 'assert' to check expression true or false
assert textureView2 != null;
textureView2.setSurfaceTextureListener(textureListener);
btnCapture = (Button)findViewById(R.id.btnCapture);
Button btnCapturewithcode = (Button)findViewById(R.id.btnCapturewithcode);
btnCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
takePicture();
}
});
btnCapturewithcode.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
photowithcode = true;
Toast.makeText(Photo_Page.this, time, Toast.LENGTH_SHORT).show();
takePicture();
}
});
}
private void takePicture() {
c = Calendar.getInstance();
time = sdftime.format(c.getTime());
date = sdf.format(c.getTime());
GlobalClass application = (GlobalClass) getApplication();
final File projectfile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), application.projectnameheader);
if (!projectfile.exists()) {
Log.d(TAG, "Folder doesn't exist, creating it...");
boolean rv = projectfile.mkdir();
}
String currentDateTimeString = java.text.DateFormat.getDateTimeInstance().format(new Date());
TextView dateandtime = (TextView) findViewById(R.id.dateandtime);
dateandtime.setText(currentDateTimeString);
gpsdisplay.setText(String.format("%.5f", latitude) + ", " + String.format("%.5f", longitude));
altitudetext.setText(String.format("%.2f", altitude) + " Meters");
if(cameraDevice == null)
return;
CameraManager manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);
try{
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
Size[] jpegSizes = null;
if(characteristics != null)
jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
.getOutputSizes(ImageFormat.JPEG);
//Capture image with custom size
int width = 480;
int height = 640;
if(jpegSizes != null && jpegSizes.length > 0)
{
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
final ImageReader reader = ImageReader.newInstance(width,height,ImageFormat.JPEG,2);
List<Surface> outputSurface = new ArrayList<>(2);
outputSurface.add(reader.getSurface());
outputSurface.add(new Surface(textureView2.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
//Check orientation base on device
time = sdftime.format(c.getTime());
date = sdf.format(c.getTime());
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(rotation));
file = new File(projectfile+"/"+(application.projectnameheader+"_"+date+"_"+time)+".jpg");
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader imageReader) {
Image image = null;
try{
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
finally {
{
if(image != null)
image.close();
}
}
}
private void save(byte[] bytes) throws IOException {
OutputStream outputStream = null;
try{
outputStream = new FileOutputStream(file);
outputStream.write(bytes);
}finally {
if(outputStream != null)
outputStream.close();
}
}
};
reader.setOnImageAvailableListener(readerListener,mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureCompleted(#NonNull CameraCaptureSession session, #NonNull CaptureRequest request, #NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
GlobalClass application = (GlobalClass) getApplication();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
Bitmap dest = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getWidth(), Bitmap.Config.ARGB_8888);
Canvas cs = new Canvas(dest);
cs.rotate(90,720 ,720);
Paint tPaint = new Paint();
tPaint.setTextSize(bitmap.getHeight()/25);
tPaint.setColor(Color.WHITE);
tPaint.setStyle(Paint.Style.FILL);
cs.drawBitmap(bitmap, 0f, 0f, null);
float height = tPaint.measureText("yY");
cs.rotate(270,720 ,720);
cs.drawText(application.projectnameheader, 25, bitmap.getHeight()+545+bitmap.getHeight()/25, tPaint);
cs.drawText(currentDateTimeString, 25, bitmap.getHeight()+615+bitmap.getHeight()/25, tPaint);
cs.drawText(String.format("%.0f",currectAzimuth) + "°", 1225, bitmap.getHeight()+690+bitmap.getHeight()/25, tPaint);
cs.drawText(directionNESW, 1235, bitmap.getHeight()+615+bitmap.getHeight()/25, tPaint);
cs.drawText(String.format("%.5f", latitude) + ", " + String.format("%.5f", longitude), 25, bitmap.getHeight()+690+bitmap.getHeight()/25, tPaint);
cs.drawText(String.format("%.2f", altitude) + " Meters", 25, bitmap.getHeight()+755+bitmap.getHeight()/25, tPaint);
cs.drawText(names, 25,bitmap.getHeight()+825+bitmap.getHeight()/25, tPaint);
Bitmap compassbitmap = BitmapFactory.decodeResource(getResources(), R.drawable.compass2);
cs.rotate(azimuth*-1,-190,2500);
cs.scale(0.25f,0.25f,-190,2500);
cs.drawBitmap(compassbitmap, 0, 0, null);
if (photowithcode==true) {
cs.drawText(code, 25, bitmap.getHeight()+895+bitmap.getHeight()/25, tPaint);
cs.drawText(note, 25, bitmap.getHeight()+970+bitmap.getHeight()/25, tPaint);
photowithcode=false;
}
try {
dest.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File(projectfile+"/"+(application.projectnameheader+"_"+date+"_"+time)+"___WITHTEXT.jpg")));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
gpslist.add(latitude + longitude);
Toast.makeText(Photo_Page.this, "Saved "+file, Toast.LENGTH_SHORT).show();
createCameraPreview();
}
};
cameraDevice.createCaptureSession(outputSurface, new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
try{
cameraCaptureSession.capture(captureBuilder.build(),captureListener,mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
}
},mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void createCameraPreview() {
try{
SurfaceTexture texture = textureView2.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(imageDimension.getWidth(),imageDimension.getHeight());
Surface surface = new Surface(texture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
if(cameraDevice == null)
return;
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(Photo_Page.this, "Changed", Toast.LENGTH_SHORT).show();
}
},null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void updatePreview() {
if(cameraDevice == null)
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE,CaptureRequest.CONTROL_MODE_AUTO);
try{
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(),null,mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void openCamera() {
CameraManager manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);
try{
cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assert map != null;
imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
//Check realtime permission if run higher API 23
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this,new String[]{
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
},REQUEST_CAMERA_PERMISSION);
return;
}
manager.openCamera(cameraId,stateCallback,null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
openCamera();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CAMERA_PERMISSION) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "You can't use camera without permission", Toast.LENGTH_SHORT).show();
finish();
}
}
}
#Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_GAME);
startBackgroundThread();
if(textureView2.isAvailable())
openCamera();
else
textureView2.setSurfaceTextureListener(textureListener);
}
#Override
protected void onPause() {
stopBackgroundThread();
super.onPause();
mSensorManager.unregisterListener(this);
}
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
final float alpha= 0.97f;
synchronized (this) {
if(sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mGravity[0] = alpha*mGravity[0]+(1-alpha)*sensorEvent.values[0];
mGravity[1] = alpha*mGravity[1]+(1-alpha)*sensorEvent.values[1];
mGravity[2] = alpha*mGravity[2]+(1-alpha)*sensorEvent.values[2];
}
if(sensorEvent.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
mGeomagnetic[0] = alpha*mGeomagnetic[0]+(1-alpha)*sensorEvent.values[0];
mGeomagnetic[1] = alpha*mGeomagnetic[1]+(1-alpha)*sensorEvent.values[1];
mGeomagnetic[2] = alpha*mGeomagnetic[2]+(1-alpha)*sensorEvent.values[2];
}
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R,I,mGravity,mGeomagnetic);
if (success){
float orientation[] = new float[3];
SensorManager.getOrientation(R,orientation);
azimuth = (float)Math.toDegrees(orientation[0]);
azimuth = (azimuth+360)%360;
//
Animation anim = new RotateAnimation(-currectAzimuth,-azimuth, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
currectAzimuth = azimuth;
degrees.setText(String.format("%.0f",currectAzimuth) + "°");
anim.setDuration(500);
anim.setRepeatCount(0);
anim.setFillAfter(true);
compass2.startAnimation(anim);
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
private void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try{
mBackgroundThread.join();
mBackgroundThread= null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void startBackgroundThread() {
mBackgroundThread = new HandlerThread("Camera Background");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
}
My goal with this code is to draw the image of a compass on a picture that is being saved to a special file on a device. I tested this by taking a picture but I noticed that, even when I changed nothing in my code, the compass would move to a random location, sometimes not even appearing.
You seem to have a lot of hard coded positions for the centre of the rotations and other items that might not be a suitable value for your actual size of bitmap backed canvas.
Probably best for the centre of rotation to be the centre of the bitmap i.e bitmap.getHeight()/2f and bitmap.getWidth()/2f and make everything relate to the size of the bitmap.
e.g.
cs.rotate(90,bitmap.getWidth()/2f ,bitmap.getHeight()/2f);
You also seem to do a rotation around a value that will change a lot depending on how you are holding the phone and what fluctuations there are in the magnetic field. The magnetic sensors reading are not that accurate and again the centre of this azimuth rotation is a weird hardcoded location (Same goes for the scale by 0.25f)
I was trying to run this code to take a photo and recognize tho photo owner, at first the user clicks the button Train and takes a picture than enter its name, after that he clicks on Recognize button and take a picture if the picture was saved the apps recognize its face if not it shows unknown person for example. The app runs good but when it crashes sometimes with this error:
FATAL EXCEPTION: main
Process: com.facedetection.app, PID: 7442
java.lang.RuntimeException: Unable to stop activity {com.facedetection.app/com.facedetection.app.TrainActivity}: CvException [org.opencv.core.CvException: cv::Exception: OpenCV(4.0.0-pre) E:\AssemCourses\opencv-master\modules\core\src\matrix.cpp:235: error: (-215:Assertion failed) s >= 0 in function 'setSize'
]
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4852)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4915)
at android.app.ActivityThread.access$1600(ActivityThread.java:211)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1759)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6946)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Caused by: CvException [org.opencv.core.CvException: cv::Exception: OpenCV(4.0.0-pre) E:\AssemCourses\opencv-master\modules\core\src\matrix.cpp:235: error: (-215:Assertion failed) s >= 0 in function 'setSize'
]
at org.opencv.face.FaceRecognizer.train_0(Native Method)
at org.opencv.face.FaceRecognizer.train(FaceRecognizer.java:133)
at com.facedetection.app.TrainActivity.trainfaces(TrainActivity.java:95)
at com.facedetection.app.TrainActivity.onStop(TrainActivity.java:351)
at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1305)
at android.app.Activity.performStop(Activity.java:6777)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4847)
Here is the classe mentionned in the error logcat:
Class TrainActivity.java:
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.InputType;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.facebook.stetho.Stetho;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.core.Size;
import org.opencv.face.Face;
import org.opencv.face.FaceRecognizer;
import org.opencv.face.LBPHFaceRecognizer;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import static org.opencv.objdetect.Objdetect.CASCADE_SCALE_IMAGE;
/**
* Created by Assem Abozaid on 6/2/2018.
*/
public class TrainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2 {
private static String TAG = TrainActivity.class.getSimpleName();
private CameraBridgeViewBase openCVCamera;
private Mat rgba,gray;
private CascadeClassifier classifier;
private MatOfRect faces;
private static final int PERMS_REQUEST_CODE = 123;
private ArrayList<Mat> images;
private ArrayList<String> imagesLabels;
private Storage local;
private String[] uniqueLabels;
FaceRecognizer recognize;
private boolean trainfaces() {
if(images.isEmpty())
return false;
List<Mat> imagesMatrix = new ArrayList<>();
for (int i = 0; i < images.size(); i++)
imagesMatrix.add(images.get(i));
Set<String> uniqueLabelsSet = new HashSet<>(imagesLabels); // Get all unique labels
uniqueLabels = uniqueLabelsSet.toArray(new String[uniqueLabelsSet.size()]); // Convert to String array, so we can read the values from the indices
int[] classesNumbers = new int[uniqueLabels.length];
for (int i = 0; i < classesNumbers.length; i++)
classesNumbers[i] = i + 1; // Create incrementing list for each unique label starting at 1
int[] classes = new int[imagesLabels.size()];
for (int i = 0; i < imagesLabels.size(); i++) {
String label = imagesLabels.get(i);
for (int j = 0; j < uniqueLabels.length; j++) {
if (label.equals(uniqueLabels[j])) {
classes[i] = classesNumbers[j]; // Insert corresponding number
break;
}
}
}
Mat vectorClasses = new Mat(classes.length, 1, CvType.CV_32SC1); // CV_32S == int
vectorClasses.put(0, 0, classes); // Copy int array into a vector
recognize = LBPHFaceRecognizer.create(3,8,8,8,200);
recognize.train(imagesMatrix, vectorClasses);
if(SaveImage())
return true;
return false;
}
public void showLabelsDialog() {
Set<String> uniqueLabelsSet = new HashSet<>(imagesLabels); // Get all unique labels
if (!uniqueLabelsSet.isEmpty()) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select label:");
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
images.remove(images.size()-1);
}
});
builder.setCancelable(false); // Prevent the user from closing the dialog
String[] uniqueLabels = uniqueLabelsSet.toArray(new String[uniqueLabelsSet.size()]); // Convert to String array for ArrayAdapter
Arrays.sort(uniqueLabels); // Sort labels alphabetically
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, uniqueLabels) {
#Override
public #NonNull
View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
TextView textView = (TextView) super.getView(position, convertView, parent);
if (getResources().getBoolean(R.bool.isTablet))
textView.setTextSize(20); // Make text slightly bigger on tablets compared to phones
else
textView.setTextSize(18); // Increase text size a little bit
return textView;
}
};
ListView mListView = new ListView(this);
mListView.setAdapter(arrayAdapter); // Set adapter, so the items actually show up
builder.setView(mListView); // Set the ListView
final AlertDialog dialog = builder.show(); // Show dialog and store in final variable, so it can be dismissed by the ListView
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
dialog.dismiss();
addLabel(arrayAdapter.getItem(position));
Log.i(TAG, "Labels Size "+imagesLabels.size()+"");
}
});
} else {
showEnterLabelDialog();
}
}
private void showEnterLabelDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Please enter your name:");
final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(input);
builder.setPositiveButton("Submit", null); // Set up positive button, but do not provide a listener, so we can check the string before dismissing the dialog
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
images.remove(images.size()-1);
}
});
builder.setCancelable(false); // User has to input a name
AlertDialog dialog = builder.create();
// Source: http://stackoverflow.com/a/7636468/2175837
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(final DialogInterface dialog) {
Button mButton = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String string = input.getText().toString().trim();
if (!string.isEmpty()) { // Make sure the input is valid
// If input is valid, dismiss the dialog and add the label to the array
dialog.dismiss();
addLabel(string);
}
}
});
}
});
// Show keyboard, so the user can start typing straight away
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
dialog.show();
}
private void addLabel(String string) {
String label = string.substring(0, 1).toUpperCase(Locale.US) + string.substring(1).trim().toLowerCase(Locale.US); // Make sure that the name is always uppercase and rest is lowercase
imagesLabels.add(label); // Add label to list of labels
Log.i(TAG, "Label: " + label);
}
public boolean SaveImage() {
File path = new File(Environment.getExternalStorageDirectory(), "TrainedData");
path.mkdirs();
String filename = "lbph_trained_data.xml";
File file = new File(path, filename);
recognize.save(file.toString());
if(file.exists())
return true;
return false;
}
public void cropedImages(Mat mat) {
Rect rect_Crop=null;
for(Rect face: faces.toArray()) {
rect_Crop = new Rect(face.x, face.y, face.width, face.height);
}
Mat croped = new Mat(mat, rect_Crop);
images.add(croped);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.train_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Stetho.initializeWithDefaults(this);
if (hasPermissions()){
Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
Log.i(TAG, "Permission Granted Before");
}
else {
requestPerms();
}
openCVCamera = (CameraBridgeViewBase)findViewById(R.id.java_camera_view);
openCVCamera.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_FRONT);
openCVCamera.setVisibility(SurfaceView.VISIBLE);
openCVCamera.setCvCameraViewListener(this);
local = new Storage(this);
Button detect = (Button)findViewById(R.id.take_picture_button);
detect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(gray.total() == 0)
Toast.makeText(getApplicationContext(), "Can't Detect Faces", Toast.LENGTH_SHORT).show();
classifier.detectMultiScale(gray,faces,1.1,3,0|CASCADE_SCALE_IMAGE, new Size(30,30));
if(!faces.empty()) {
if(faces.toArray().length > 1)
Toast.makeText(getApplicationContext(), "Mutliple Faces Are not allowed", Toast.LENGTH_SHORT).show();
else {
if(gray.total() == 0) {
Log.i(TAG, "Empty gray image");
return;
}
cropedImages(gray);
showLabelsDialog();
Toast.makeText(getApplicationContext(), "Face Detected", Toast.LENGTH_SHORT).show();
}
}else
Toast.makeText(getApplicationContext(), "Unknown Face", Toast.LENGTH_SHORT).show();
}
});
}
#SuppressLint("WrongConstant")
private boolean hasPermissions(){
int res = 0;
//string array of permissions,
String[] permissions = new String[]{Manifest.permission.CAMERA};
for (String perms : permissions){
res = checkCallingOrSelfPermission(perms);
if (!(res == PackageManager.PERMISSION_GRANTED)){
return false;
}
}
return true;
}
private void requestPerms(){
String[] permissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
requestPermissions(permissions,PERMS_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
boolean allowed = true;
switch (requestCode){
case PERMS_REQUEST_CODE:
for (int res : grantResults){
// if user granted all permissions.
allowed = allowed && (res == PackageManager.PERMISSION_GRANTED);
}
break;
default:
// if user not granted permissions.
allowed = false;
break;
}
if (allowed){
//user granted all permissions we can perform our task.
Log.i(TAG, "Permission has been added");
}
else {
// we will give warning to user that they haven't granted permissions.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA) || shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE) ||
shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)){
Toast.makeText(this, "Permission Denied.", Toast.LENGTH_SHORT).show();
}
}
}
}
private BaseLoaderCallback callbackLoader = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch(status) {
case BaseLoaderCallback.SUCCESS:
faces = new MatOfRect();
openCVCamera.enableView();
images = local.getListMat("images");
imagesLabels = local.getListString("imagesLabels");
break;
default:
super.onManagerConnected(status);
break;
}
}
};
#Override
protected void onPause() {
super.onPause();
if(openCVCamera != null)
openCVCamera.disableView();
}
#Override
protected void onStop() {
super.onStop();
if (images != null && imagesLabels != null) {
local.putListMat("images", images);
local.putListString("imagesLabels", imagesLabels);
Log.i(TAG, "Images have been saved");
if(trainfaces()) {
images.clear();
imagesLabels.clear();
}
}
}
#Override
protected void onDestroy(){
super.onDestroy();
if(openCVCamera != null)
openCVCamera.disableView();
}
#Override
protected void onResume(){
super.onResume();
if(OpenCVLoader.initDebug()) {
Log.i(TAG, "System Library Loaded Successfully");
callbackLoader.onManagerConnected(BaseLoaderCallback.SUCCESS);
} else {
Log.i(TAG, "Unable To Load System Library");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION, this, callbackLoader);
}
}
#Override
public void onCameraViewStarted(int width, int height) {
rgba = new Mat();
gray = new Mat();
classifier = FileUtils.loadXMLS(this, "lbpcascade_frontalface_improved.xml");
}
#Override
public void onCameraViewStopped() {
rgba.release();
gray.release();
}
#Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
Mat mGrayTmp = inputFrame.gray();
Mat mRgbaTmp = inputFrame.rgba();
int orientation = openCVCamera.getScreenOrientation();
if (openCVCamera.isEmulator()) // Treat emulators as a special case
Core.flip(mRgbaTmp, mRgbaTmp, 1); // Flip along y-axis
else {
switch (orientation) { // RGB image
case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
Core.flip(mRgbaTmp, mRgbaTmp, 0); // Flip along x-axis
break;
case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
Core.flip(mRgbaTmp, mRgbaTmp, 1); // Flip along y-axis
break;
}
switch (orientation) { // Grayscale image
case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
Core.transpose(mGrayTmp, mGrayTmp); // Rotate image
Core.flip(mGrayTmp, mGrayTmp, -1); // Flip along both axis
break;
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
Core.transpose(mGrayTmp, mGrayTmp); // Rotate image
break;
case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
Core.flip(mGrayTmp, mGrayTmp, 1); // Flip along y-axis
break;
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
Core.flip(mGrayTmp, mGrayTmp, 0); // Flip along x-axis
break;
}
}
gray = mGrayTmp;
rgba = mRgbaTmp;
Imgproc.resize(gray, gray, new Size(200,200.0f/ ((float)gray.width()/ (float)gray.height())));
return rgba;
}
}
The Lines of Errors mentionned in the logcat refers to those java code lines:
In TrainActivity.java:
recognize = LBPHFaceRecognizer.create(3,8,8,8,200);
recognize.train(imagesMatrix, vectorClasses);
And
if(trainfaces()) {
images.clear();
imagesLabels.clear();
}
Do you guys have any idea about this problem and how to fix it?
PS: I am a beginner with OpenCv.
You can solve it by reset preferences onCreate TrainActivity
// -------------------------------
// reset preferences
local = new Storage(this);
images = new ArrayList<>();
imagesLabels = new ArrayList<>();
local.putListMat("images", images);
local.putListString("imagesLabels", imagesLabels);
// -------------------------------
I have an app that records the accelerometer data and send a SMS when a treshhold is passed. It works fine when the phone is awake. What do I need to do so this is also do the same when the phone is locked/sleeping:
I have two activites SendSMSActivity.java:
package com.example.sendsms;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.Menu;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.FilterQueryProvider;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class SendSMSActivity extends Activity implements SensorEventListener {
SendSMS mSender = new SendSMS();
private SensorManager senSensorManager;
private Sensor senAccelerometer;
private long lastUpdate;
private float last_x, last_y, last_z;
//Contacts variable
AutoCompleteTextView emailText;
ContentResolver cr;
SimpleCursorAdapter emailAdapter;
protected void onResume() {
super.onResume();
senSensorManager.registerListener(this, senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
senSensorManager.unregisterListener(this);
}
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
//To change body of implemented methods use File | Settings | File Templates.
Sensor mySensor = sensorEvent.sensor;
if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) {
float x = sensorEvent.values[0];
float y = sensorEvent.values[1];
float z = sensorEvent.values[2];
long curTime = System.currentTimeMillis();
// only allow one update every 100ms.
if ((curTime - lastUpdate) > 100) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
float speed = Math.abs(x+y+z - last_x - last_y - last_z)/ diffTime * 10000;
TextView threshText = (TextView)findViewById(R.id.thresh);
if (speed > Float.parseFloat(threshText.getText().toString())) {
Toast.makeText(this, "shake detected w/ speed: " + speed, Toast.LENGTH_SHORT).show();
Toast.makeText(this, "shake detected w/ speed: " + speed, Toast.LENGTH_SHORT).show();
TextView resultText = (TextView)findViewById(R.id.xacc);
resultText.setText("shake detected w/ speed: " + speed);
sendit2();
}
last_x = x;
last_y = y;
last_z = z;
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// can be safely ignored for this demo
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Get an instance of the SensorManager
senSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
senSensorManager.registerListener(this, senAccelerometer , SensorManager.SENSOR_DELAY_NORMAL);
//Contacts
cr = getContentResolver();
emailText = (AutoCompleteTextView) findViewById(R.id.mobileNo);
String[] fromCols = {
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.DATA,
};
int[] toViewIds = { R.id.list_name, R.id.list_email };
emailAdapter = new SimpleCursorAdapter(this, R.layout.email_and_name, getNamesAndEmails(null), fromCols, toViewIds);
// Important 1: You have to provide a way of making the chosen choice look presentable.
// emailAdapter.setStringConversionColumn(1); // 1=DISPLAY_NAME, 2=Email
emailAdapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() {
#Override
public CharSequence convertToString(Cursor cursor) {
return String.format("%s <%s>", cursor.getString(1).trim(), cursor.getString(2).trim());
}
});
// Important 2: You have to provide a query containing the values on demand
emailAdapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
String partialItemName = null;
if (constraint != null) {
partialItemName = constraint.toString();
}
return getNamesAndEmails(partialItemName);
}
});
emailText.setAdapter(emailAdapter);
}
//Contacts
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
final static String[] PROJECTION = new String[] {
ContactsContract.RawContacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.DATA,
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,
};
/** Get the contacts that have email addresses matching "partialName".
* #author Modified from code obtained from
* http://stackoverflow.com/questions/5205999/android-get-a-cursor-only-with-contacts-that-have-an-email-listed-android-2-0
* #return
*/
Cursor getNamesAndEmails(String partialName) {
// Look for partialName either in display name (person name) or in email
final String filter =
ContactsContract.Contacts.DISPLAY_NAME + " LIKE '%" + partialName + "%'" +
" OR " +
ContactsContract.CommonDataKinds.Phone.DATA + " LIKE '%" + partialName + "%'";
// If display name contains "#" (maybe it's null so Contacts provides email here),
// order by email, else order by display name.
final String order = "CASE WHEN "
+ ContactsContract.Contacts.DISPLAY_NAME
+ " NOT LIKE '%#%' THEN 1 ELSE 2 END, "
+ ContactsContract.Contacts.DISPLAY_NAME
+ ", "
+ ContactsContract.CommonDataKinds.Phone.DATA
+ " COLLATE NOCASE";
// Now make a Cursor containing the contacts that now match partialName as per "filter".
return cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, filter, null, order);
}
public void sendit(View v) {
TextView mobileNum = (TextView)findViewById(R.id.mobileNo);
boolean success = mSender.sendSMSMessage(mobileNum.getText().toString(),
// This is standard lorem-ipsum text, do not bother
// trying to wrap it, there's about 500 characters...
"Movement detected."
);
Toast.makeText(this, "Message sent " + (
success ? "successfully" : "unsuccessfully"),
Toast.LENGTH_SHORT).show();
TextView resultText = (TextView)findViewById(R.id.xacc);
resultText.setText("Message Sent");
}
public void sendit2() {
TextView mobileNum = (TextView)findViewById(R.id.mobileNo);
boolean success = mSender.sendSMSMessage(mobileNum.getText().toString(),
// This is standard lorem-ipsum text, do not bother
// trying to wrap it, there's about 500 characters...
"Movement detected."
);
Toast.makeText(this, "Message sent " + (
success ? "successfully" : "unsuccessfully"),
Toast.LENGTH_SHORT).show();
TextView resultText = (TextView)findViewById(R.id.xacc);
resultText.setText("Message Sent");
}
}
and SendSMS.java:
package com.example.sendsms;
import java.util.ArrayList;
import android.telephony.SmsManager;
import android.util.Log;
/** The code for dealing with the SMS manager;
* called from the GUI code.
*/
public class SendSMS {
static String TAG = "SendSMS";
SmsManager mSMSManager = null;
/* The list of message parts our messge
* gets broken up into by SmsManger */
ArrayList<String> mFragmentList = null;
/* Service Center - not used */
String mServiceCentreAddr = null;
SendSMS() {
mSMSManager = SmsManager.getDefault();
}
/* Called from the GUI to send one message to one destination */
public boolean sendSMSMessage(
String aDestinationAddress,
String aMessageText) {
if (mSMSManager == null) {
return (false);
}
mFragmentList = mSMSManager.divideMessage(aMessageText);
int fragmentCount = mFragmentList.size();
if (fragmentCount > 1) {
Log.d(TAG, "Sending " + fragmentCount + " parts");
mSMSManager.sendMultipartTextMessage(aDestinationAddress,
mServiceCentreAddr,
mFragmentList, null, null);
} else {
Log.d(TAG, "Sendine one part");
mSMSManager.sendTextMessage(aDestinationAddress,
mServiceCentreAddr,
aMessageText, null, null);
}
return true;
}
}
I'm a new programmer,recently i have a bug but can't solve
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.Bl
uetoothChat/com.example.android.BluetoothFileTran.FileTranActivity}:
java.lang.NullPointerException
logcat stack trace
04-26 10:19:43.613: E/BluetoothChat(21754): +++ ON CREATE +++
04-26 10:19:44.213: E/CheckPermission(21754): _bluetooth code = 1
04-26 10:19:44.213: E/BluetoothChat(21754): ++ ON START ++
04-26 10:19:44.233: E/BluetoothChat(21754): + ON RESUME +
04-26 10:19:44.233: E/CheckPermission(21754): _bluetooth code = 13
04-26 10:19:45.643: E/BluetoothChat(21754): - ON PAUSE -
04-26 10:19:47.223: E/BluetoothChat(21754): + ON RESUME +
04-26 10:19:55.093: E/BluetoothChat(21754): - ON PAUSE -
04-26 10:20:21.363: E/AndroidRuntime(21754): FATAL EXCEPTION: main
04-26 10:20:21.363: E/AndroidRuntime(21754): Process: com.example.android.BluetoothChat, PID: 21754
04-26 10:20:21.363: E/AndroidRuntime(21754): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.BluetoothChat/com.example.android.BluetoothFileTran.FileTranActivity}: java.lang.NullPointerException
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2190)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.ActivityThread.access$800(ActivityThread.java:139)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.os.Handler.dispatchMessage(Handler.java:102)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.os.Looper.loop(Looper.java:136)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.ActivityThread.main(ActivityThread.java:5049)
04-26 10:20:21.363: E/AndroidRuntime(21754): at java.lang.reflect.Method.invokeNative(Native Method)
04-26 10:20:21.363: E/AndroidRuntime(21754): at java.lang.reflect.Method.invoke(Method.java:515)
04-26 10:20:21.363: E/AndroidRuntime(21754): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:818)
04-26 10:20:21.363: E/AndroidRuntime(21754): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:634)
04-26 10:20:21.363: E/AndroidRuntime(21754): at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
04-26 10:20:21.363: E/AndroidRuntime(21754): at dalvik.system.NativeStart.main(Native Method)
04-26 10:20:21.363: E/AndroidRuntime(21754): Caused by: java.lang.NullPointerException
04-26 10:20:21.363: E/AndroidRuntime(21754): at com.example.android.BluetoothFileTran.FileTranActivity.onCreate(FileTranActivity.java:66)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.Activity.performCreate(Activity.java:5293)
04-26 10:20:21.363: E/AndroidRuntime(21754): at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method)
04-26 10:20:21.363: E/AndroidRuntime(21754): at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:631)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.Activity.performCreate(Native Method)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2154)
04-26 10:20:21.363: E/AndroidRuntime(21754): ... 12 more
here is Bluetoooth.java
package com.example.android.BluetoothChat;
import com.example.android.BluetoothChat.R;
import com.example.android.BluetoothChat.service.BluetoothChatService;
import com.example.android.BluetoothFileTran.FileTranActivity;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ContentValues;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class BluetoothChat extends Activity {
public static final String SEND_FILE_NAME = "sendFileName";
public static final int REQUEST_FILE = 1000;
private static String mSendFileName ;
private Handler mOthHandler;
private static String mAddress ;
private static final String TAG = "BluetoothChat";
private static final boolean D = true;
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
private ListView mConversationView;
private EditText mOutEditText;
private Button mSendButton;
private String mConnectedDeviceName = null;
private ArrayAdapter<String> mConversationArrayAdapter;
private StringBuffer mOutStringBuffer;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothChatService mChatService = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(D) Log.e(TAG, "+++ ON CREATE +++");
setContentView(R.layout.main);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
}
#Override
public void onStart() {
super.onStart();
if(D) Log.e(TAG, "++ ON START ++");
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
} else {
if (mChatService == null) setupChat();
}
}
private void setupChat() {
Log.d(TAG, "setupChat()");
mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);
mConversationView = (ListView) findViewById(R.id.in);
mConversationView.setAdapter(mConversationArrayAdapter);
mOutEditText = (EditText) findViewById(R.id.edit_text_out);
mOutEditText.setOnEditorActionListener(mWriteListener);
mSendButton = (Button) findViewById(R.id.button_send);
mSendButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
TextView view = (TextView) findViewById(R.id.edit_text_out);
String message = view.getText().toString();
sendMessage(message);
}
});
mChatService = new BluetoothChatService(this, mHandler);
mOutStringBuffer = new StringBuffer("");
}
#Override
public synchronized void onResume() {
super.onResume();
if(D) Log.e(TAG, "+ ON RESUME +");
if (mChatService != null) {
if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
mChatService.start();
}
}
}
private TextView.OnEditorActionListener mWriteListener =
new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
//EditorInfo.IME_NULL KeyEvent.ACTION_UP
if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
String message = view.getText().toString();
sendMessage(message);
}
if(D) Log.i(TAG, "END onEditorAction");
return true;
}
};
#Override
public synchronized void onPause() {
super.onPause();
if(D) Log.e(TAG, "- ON PAUSE -");
}
#Override
public void onStop() {
super.onStop();
if(D) Log.e(TAG, "-- ON STOP --");
}
#Override
public void onDestroy() {
super.onDestroy();
if (mChatService != null) mChatService.stop();
if(D) Log.e(TAG, "--- ON DESTROY ---");
}
private void sendMessage(String message) {
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
if (message.length() > 0) {
byte[] send = message.getBytes();
mChatService.write(send);
mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case BluetoothChatService.STATE_CONNECTED:
mConversationArrayAdapter.clear();
break;
case BluetoothChatService.STATE_CONNECTING:
break;
case BluetoothChatService.STATE_LISTEN:
case BluetoothChatService.STATE_NONE:
break;
}
break;
case MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
String writeMessage = new String(writeBuf);
mConversationArrayAdapter.add("Me: " + writeMessage);
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
String readMessage = new String(readBuf, 0, msg.arg1);
mConversationArrayAdapter.add(mConnectedDeviceName+": " + readMessage);
break;
case MESSAGE_DEVICE_NAME:
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
// mAddress = msg.getData().getString(DEVICE_ADDRESS);
Toast.makeText(getApplicationContext(), "Connected to "
+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
Toast.LENGTH_SHORT).show();
break;
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(D) Log.d(TAG, "onActivityResult " + resultCode);
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:
if (resultCode == Activity.RESULT_OK) {
mAddress = data.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mAddress);
mChatService.connect(device);
}
break;
case REQUEST_ENABLE_BT:
if (resultCode == Activity.RESULT_OK) {
setupChat();
} else {
Log.d(TAG, "BT not enabled");
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
finish();
}
break;
case REQUEST_FILE:
if (resultCode == Activity.RESULT_OK) {
mSendFileName = data.getExtras().getString(SEND_FILE_NAME);
doSendFileByBluetooth();
}
break;
}
}
private void doSendFileByBluetooth() {
String filePath = mSendFileName.trim();
if(!filePath.equals("null")){
if(null == mOthHandler){
HandlerThread handlerThread = new HandlerThread("other_thread");
handlerThread.start();
mOthHandler = new Handler(handlerThread.getLooper());
}
mOthHandler.post(new Runnable() {
#Override
public void run() {
ContentValues cv = new ContentValues();
String uri = "file://" + mSendFileName.trim();
cv.put("uri", uri);
cv.put("destination", mAddress.trim());
cv.put("direction", 0);
Long ts = System.currentTimeMillis();
cv.put("timestamp", ts);
getContentResolver().insert(Uri.parse("content://com.android.bluetooth.opp/btopp"), cv);
}
});
}else {
Toast.makeText(BluetoothChat.this, "请选择要发送的文件!", Toast.LENGTH_LONG).show();
}
}
private void ensureDiscoverable() {
if(D) Log.d(TAG, "ensure discoverable");
if (mBluetoothAdapter.getScanMode() !=
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.option_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.scan:
Intent serverIntent = new Intent(this, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
return true;
case R.id.discoverable:
ensureDiscoverable();
return true;
case R.id.file_transport:
Intent fileIntent = new Intent(this, FileTranActivity.class);
startActivityForResult(fileIntent, REQUEST_FILE);
return true;
}
return false;
}
}
here is FileTranActivity.java
package com.example.android.BluetoothFileTran;
import java.io.File;
import com.example.android.BluetoothChat.BluetoothChat;
import com.example.android.BluetoothChat.R;
import com.example.android.BluetoothFileTran.adapter.AdapterManager;
import com.example.android.BluetoothFileTran.adapter.FileListAdapter;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class FileTranActivity extends Activity {
ListView mFileListView;
FileListAdapter mFileListAdapter;
AdapterManager mAdapterManager;
private Handler mOtherHandler;
private Runnable updateFileListRunnable;
private File file;
private String sdcardPath;
private String path;
Button mBackBtn;
Button mEnsureBtn;
Button mCancelBtn;
TextView mLastClickView;
TextView mNowClickView;
private boolean isSelected = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.file_list);
setResult(Activity.RESULT_CANCELED);
mFileListView = (ListView) findViewById(R.id.fileListView);
mBackBtn = (Button) findViewById(R.id.selectFileBackBtn);
mEnsureBtn = (Button) findViewById(R.id.selectFileEnsureBtn);
mCancelBtn = (Button) findViewById(R.id.selectFileCancelBtn);
sdcardPath = Environment.getExternalStorageDirectory().getAbsolutePath();
path = sdcardPath;
mAdapterManager = BluetoothApplication.getInstance().getAdapterManager();
mFileListView.setAdapter(mAdapterManager.getFileListAdapter());
mAdapterManager.updateFileListAdapter(path);
mFileListView.setOnItemClickListener(mFileListOnItemClickListener);
mBackBtn.setOnClickListener(mBackBtnClickListener);
mEnsureBtn.setOnClickListener(mEnsureBtnClickListener);
mCancelBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FileTranActivity.this.finish();
}
});
}
private OnItemClickListener mFileListOnItemClickListener = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
file = (File) mFileListView.getAdapter().getItem(position);
if(file.isFile()){
if(null != mLastClickView){
mLastClickView.setTextColor(Color.WHITE);
}
mNowClickView = (TextView) view.findViewById(R.id.fileNameTV);
mNowClickView.setTextColor(Color.BLUE);
isSelected = true;
mLastClickView = mNowClickView;
}else {
path = file.getAbsolutePath();
updateFileList();
}
}
};
private OnClickListener mBackBtnClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
if(path.equals(sdcardPath)){
return ;
}
path = path.substring(0, path.lastIndexOf("/"));
updateFileList();
}
};
private OnClickListener mEnsureBtnClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
if(!isSelected){
Toast.makeText(FileTranActivity.this, "请选择文件!", Toast.LENGTH_LONG).show();
return ;
}
Intent intent = new Intent();
intent.putExtra(BluetoothChat.SEND_FILE_NAME, file.getAbsolutePath());
setResult(Activity.RESULT_OK, intent);
FileTranActivity.this.finish();
}
};
private void updateFileList() {
if(null != mLastClickView){
mLastClickView.setTextColor(Color.WHITE);
mLastClickView = null;
isSelected = false;
}
if(null == updateFileListRunnable){
updateFileListRunnable = new Runnable() {
#Override
public void run() {
mAdapterManager.updateFileListAdapter(path);
}
};
}
if(null == mOtherHandler){
HandlerThread handlerThread = new HandlerThread("other_thread");
handlerThread.start();
mOtherHandler = new Handler(handlerThread.getLooper());
}
mOtherHandler.post(updateFileListRunnable);
}
}
then ,I find it point out the error in the FileTranActivity.java
mAdapterManager = BluetoothApplication.getInstance().getAdapterManager();
so ,here is BluetoothApplication.java
package com.example.android.BluetoothFileTran;
import com.example.android.BluetoothFileTran.adapter.AdapterManager;
import com.example.android.BluetoothFileTran.adapter.util.TouchObject;
import android.app.Application;
public class BluetoothApplication extends Application {
private static BluetoothApplication application;
private AdapterManager mAdapterManager;
private TouchObject mTouchObject;
#Override
public void onCreate() {
super.onCreate();
if(null == application){
application = this;
}
mTouchObject = new TouchObject();
}
public static BluetoothApplication getInstance(){
return application;
}
public AdapterManager getAdapterManager() {
return mAdapterManager;
}
public void setAdapterManager(AdapterManager adapterManager) {
this.mAdapterManager = adapterManager;
}
public TouchObject getTouchObject() {
return mTouchObject;
}
public void setTouchObject(TouchObject touchObject) {
this.mTouchObject = touchObject;
}
}
and AdapterManager.java
package com.example.android.BluetoothFileTran.adapter;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.Handler;
import com.example.android.BluetoothChat.R;
import com.example.android.BluetoothFileTran.adapter.FileListAdapter;
public class AdapterManager {
private Context mContext;
private FileListAdapter mFileListAdapter;
private List<BluetoothDevice> mDeviceList;
private List<File> mFileList;
private Handler mainHandler;
public AdapterManager(Context context){
this.mContext = context;
}
public FileListAdapter getFileListAdapter(){
if(null == mFileListAdapter){
mFileList = new ArrayList<File>();
mFileListAdapter = new FileListAdapter(mContext, mFileList, R.layout.file_list_item);
}
return mFileListAdapter;
}
public void clearDevice(){
if(null != mDeviceList){
mDeviceList.clear();
}
}
public void addDevice(BluetoothDevice bluetoothDevice){
mDeviceList.add(bluetoothDevice);
}
public void changeDevice(int listId, BluetoothDevice bluetoothDevice){
mDeviceList.remove(listId);
mDeviceList.add(listId, bluetoothDevice);
}
public void updateFileListAdapter(String path){
mFileList.clear();
mFileList.addAll(getFileList(path));
if(null == mainHandler){
mainHandler = new Handler(mContext.getMainLooper());
}
mainHandler.post(new Runnable() {
#Override
public void run() {
mFileListAdapter.notifyDataSetChanged();
}
});
}
public List<BluetoothDevice> getDeviceList() {
return mDeviceList;
}
public static List<File> getFileList(String path){
List<File> fileList = new ArrayList<File>();
File[] files = new File(path).listFiles();
if(files.length > 0){
List<File> allFolder = new ArrayList<File>();
List<File> allFile = new ArrayList<File>();
for(File file : files){
if(file.isFile()){
allFile.add(file);
}else {
allFolder.add(file);
}
}
fileList.addAll(allFolder);
fileList.addAll(allFile);
}
return fileList;
}
}
my xml is
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.BluetoothChat"
android:versionCode="1"
android:versionName="1.0" xmlns:tools="http://schemas.android.com/tools">
<uses-sdk
android:minSdkVersion="6"
android:targetSdkVersion="18" tools:ignore="OldTargetApi"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:label="#string/app_name"
android:icon="#drawable/ic_launcher"
android:theme="#style/AppTheme" >
<activity android:name="com.example.android.BluetoothChat.BluetoothChat"
android:label="#string/app_name"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.example.android.BluetoothChat.DeviceListActivity"
android:label="#string/select_device"
android:theme="#android:style/Theme.Dialog"
/>
<activity android:name="com.example.android.BluetoothFileTran.FileTranActivity"
android:label="#string/select_file"
android:theme="#android:style/Theme.Dialog"
/>
</application>
</manifest>
Register in the AndroidManifest the BluetoothFileTran class as application name in application tag:
<application
android:allowBackup="true"
android:name="com.example.android.BluetoothFileTran"
...
Without this, the BluetoothFileTran will not be loaded, and onCreate will never invoked.
This will return a null reference in BluetoothApplication.getInstance(), which are causing your NullPointerException.
Reference
Notice: Your package in manifest, package="com.example.android.BluetoothChat" is different from the package that BluetoothFileTran is located (not in one of childs). I recommend you to use the package com.example.android instead of com.example.android.BluetoothChat in manifest tag.
I try to get current location and user activity, following the guide from
http://j.mp/io13-location the "checkpoint_final"
but i got those error when i run the program.
my logCat:
02-21 18:12:38.439: E/AndroidRuntime(3798): FATAL EXCEPTION: main
02-21 18:12:38.439: E/AndroidRuntime(3798): Process: com.android.google.codelab.location, PID: 3798
02-21 18:12:38.439: E/AndroidRuntime(3798): java.lang.RuntimeException: Unable to resume activity {com.android.google.codelab.location/com.android.google.codelab.location.LocationActivity}: java.lang.IllegalStateException: Not connected. Call connect() and wait for onConnected() to be called.
02-21 18:12:38.439: E/AndroidRuntime(3798): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2788)
02-21 18:12:38.439: E/AndroidRuntime(3798): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2817)
02-21 18:12:38.439: E/AndroidRuntime(3798): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
02-21 18:12:38.439: E/AndroidRuntime(3798): at android.app.ActivityThread.access$800(ActivityThread.java:135)
02-21 18:12:38.439: E/AndroidRuntime(3798): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
02-21 18:12:38.439: E/AndroidRuntime(3798): at android.os.Handler.dispatchMessage(Handler.java:102)
02-21 18:12:38.439: E/AndroidRuntime(3798): at android.os.Looper.loop(Looper.java:136)
02-21 18:12:38.439: E/AndroidRuntime(3798): at android.app.ActivityThread.main(ActivityThread.java:5017)
02-21 18:12:38.439: E/AndroidRuntime(3798): at java.lang.reflect.Method.invokeNative(Native Method)
02-21 18:12:38.439: E/AndroidRuntime(3798): at java.lang.reflect.Method.invoke(Method.java:515)
02-21 18:12:38.439: E/AndroidRuntime(3798): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-21 18:12:38.439: E/AndroidRuntime(3798): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-21 18:12:38.439: E/AndroidRuntime(3798): at dalvik.system.NativeStart.main(Native Method)
02-21 18:12:38.439: E/AndroidRuntime(3798): Caused by: java.lang.IllegalStateException: Not connected. Call connect() and wait for onConnected() to be called.
02-21 18:12:38.439: E/AndroidRuntime(3798): at com.google.android.gms.internal.dk.bB(Unknown Source)
02-21 18:12:38.439: E/AndroidRuntime(3798): at com.google.android.gms.internal.fm.a(Unknown Source)
02-21 18:12:38.439: E/AndroidRuntime(3798): at com.google.android.gms.internal.fm$c.bB(Unknown Source)
02-21 18:12:38.439: E/AndroidRuntime(3798): at com.google.android.gms.internal.fl.requestLocationUpdates(Unknown Source)
02-21 18:12:38.439: E/AndroidRuntime(3798): at com.google.android.gms.internal.fm.requestLocationUpdates(Unknown Source)
02-21 18:12:38.439: E/AndroidRuntime(3798): at com.google.android.gms.internal.fm.requestLocationUpdates(Unknown Source)
02-21 18:12:38.439: E/AndroidRuntime(3798): at com.google.android.gms.location.LocationClient.requestLocationUpdates(Unknown Source)
02-21 18:12:38.439: E/AndroidRuntime(3798): at com.android.google.codelab.location.LocationActivity.restartLocationClient(LocationActivity.java:248)
02-21 18:12:38.439: E/AndroidRuntime(3798): at com.android.google.codelab.location.LocationActivity.onResume(LocationActivity.java:197)
02-21 18:12:38.439: E/AndroidRuntime(3798): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1192)
02-21 18:12:38.439: E/AndroidRuntime(3798): at android.app.Activity.performResume(Activity.java:5310)
02-21 18:12:38.439: E/AndroidRuntime(3798): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2778)
02-21 18:12:38.439: E/AndroidRuntime(3798): ... 12 more
my Code
public class LocationActivity extends FragmentActivity {
public static String TAG = "LocationActivity";
public static boolean isAppForeground = false;
private static final int ERROR_DIALOG_ON_CREATE_REQUEST_CODE = 4055;
private static final int ERROR_DIALOG_ON_RESUME_REQUEST_CODE = 4056;
// Shared variables
private GoogleMap mMap;
private Dialog errorDialog;
// Location Request variables
private LocationClient mLocationClient;
private TextView mLocationStatus;
private LocationCallback mLocationCallback = new LocationCallback();
private Location mLastLocation;
private static final int LOCATION_UPDATES_INTERVAL = 10000; // Setting 10 sec interval for location updates
// Activity Recognition variables
private ActivityRecognitionClient mActivityRecognitionClient;
private ActivityRecognitionCallback mActivityRecognitionCallback = new ActivityRecognitionCallback();
public static final String ACTION_ACTIVITY_RECOGNITION =
"com.android.google.codelab.location.LocationActivity.ACTIVITY_RECOGNITION";
private static final int ACTIVITY_UPDATES_INTERVAL = 4000;
private PendingIntent mActivityRecognitionPendingIntent;
private Switch mSwitch;
private ActivityRecognitionIntentReceiver mActivityRecognitionIntentReceiver;
// Geo Fencing variables
private GeoFenceCallback mGeoFenceCallback = new GeoFenceCallback();
private int id = 0;
private static final float GEOFENCE_RADIUS = 100;
private HashMap<String, Circle> mGeoFences;
private HashMap<String, Circle> mTriggeringFences;
public static final String ACTION_GEOFENCE =
"com.android.google.codelab.location.LocationActivity.GEOFENCE";
private TextView mGeoFenceStatus;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
checkGooglePlayServiceAvailability(ERROR_DIALOG_ON_CREATE_REQUEST_CODE);
}
private void init() {
// Initialize map
if (mMap == null) {
FragmentManager myFragmentManager = getSupportFragmentManager();
SupportMapFragment myMapFragment =
(SupportMapFragment) myFragmentManager.findFragmentById(R.id.map);
mMap = myMapFragment.getMap();
}
// Initialize Location Client
mLocationStatus = (TextView) findViewById(R.id.location_status);
if (mLocationClient == null) {
mLocationClient = new LocationClient(this, mLocationCallback, mLocationCallback);
Log.v(LocationActivity.TAG, "Location Client connect");
if (!(mLocationClient.isConnected() || mLocationClient.isConnecting())) {
mLocationClient.connect();
}
}
// Initialize Action Recognition
if (mActivityRecognitionClient == null) {
mActivityRecognitionClient =
new ActivityRecognitionClient(this,
mActivityRecognitionCallback, mActivityRecognitionCallback);
}
mSwitch = (Switch) findViewById(R.id.swtich);
mSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
startActivityDetection(buttonView);
} else {
stopActivityDetection(buttonView);
}
}
});
if (mActivityRecognitionIntentReceiver == null) {
mActivityRecognitionIntentReceiver = new ActivityRecognitionIntentReceiver();
registerReceiver(mActivityRecognitionIntentReceiver,
new IntentFilter(LocationActivity.ACTION_ACTIVITY_RECOGNITION));
}
// Initialize Geo Fencing
mGeoFenceStatus = (TextView) findViewById(R.id.geo_fence_status);
if (mGeoFences == null) {
mGeoFences = new HashMap<String, Circle>();
}
if (mTriggeringFences == null) {
mTriggeringFences = new HashMap<String, Circle>();
}
// Setup map to allow adding Geo Fences
mMap.getUiSettings().setAllGesturesEnabled(true);
mMap.setOnMapLongClickListener(mGeoFenceCallback);
}
#Override
public void onPause() {
super.onPause();
// Indicate the application is in background
isAppForeground = false;
if (mLocationClient.isConnected()) {
mLocationClient.removeLocationUpdates(mLocationCallback);
mLocationClient.disconnect();
}
}
#Override
public void onResume() {
super.onResume();
// Indicate the application is in foreground
isAppForeground = true;
checkGooglePlayServiceAvailability(ERROR_DIALOG_ON_RESUME_REQUEST_CODE);
restartLocationClient();
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mActivityRecognitionIntentReceiver);
mActivityRecognitionIntentReceiver = null;
}
private void checkGooglePlayServiceAvailability(int requestCode) {
// Query for the status of Google Play services on the device
int statusCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(getBaseContext());
if (statusCode == ConnectionResult.SUCCESS) {
init();
} else {
if (GooglePlayServicesUtil.isUserRecoverableError(statusCode)) {
errorDialog = GooglePlayServicesUtil.getErrorDialog(statusCode,
this, requestCode);
errorDialog.show();
} else {
// Handle unrecoverable error
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case ERROR_DIALOG_ON_CREATE_REQUEST_CODE:
init();
break;
case ERROR_DIALOG_ON_RESUME_REQUEST_CODE:
restartLocationClient();
break;
}
}
}
private void restartLocationClient() {
if (!(mLocationClient.isConnected() || mLocationClient.isConnecting())) {
mLocationClient.connect(); // Somehow it becomes connected here
return;
}
LocationRequest request = LocationRequest.create();
request.setInterval(LOCATION_UPDATES_INTERVAL);
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationClient.requestLocationUpdates(request, mLocationCallback);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuItem menuItem = menu.add(R.string.clear_map);
menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
menuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
clearMap();
return true;
}
});
return true;
}
public void clearMap() {
mMap.clear();
mLastLocation = null;
mGeoFenceCallback.removeGeoFences();
}
private class LocationCallback implements ConnectionCallbacks, OnConnectionFailedListener,
LocationListener {
#Override
public void onConnected(Bundle connectionHint) {
Log.v(LocationActivity.TAG, "Location Client connected");
// Display last location
Location location = mLocationClient.getLastLocation();
if (location != null) {
handleLocation(location);
}
// Request for location updates
LocationRequest request = LocationRequest.create();
request.setInterval(LOCATION_UPDATES_INTERVAL);
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationClient.requestLocationUpdates(request, mLocationCallback);
}
#Override
public void onDisconnected() {
Log.v(LocationActivity.TAG, "Location Client disconnected by the system");
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.v(LocationActivity.TAG, "Location Client connection failed");
}
#Override
public void onLocationChanged(Location location) {
if (location == null) {
Log.v(LocationActivity.TAG, "onLocationChanged: location == null");
return;
}
// Add a marker iff location has changed.
if (mLastLocation != null &&
mLastLocation.getLatitude() == location.getLatitude() &&
mLastLocation.getLongitude() == location.getLongitude()) {
return;
}
handleLocation(location);
}
private void handleLocation(Location location) {
// Update the mLocationStatus with the lat/lng of the location
Log.v(LocationActivity.TAG, "LocationChanged == #" +
location.getLatitude() + "," + location.getLongitude());
mLocationStatus.setText("Location changed #" + location.getLatitude() + "," +
location.getLongitude());
// Add a marker of that location to the map
LatLng latlongzoom = new LatLng(location.getLatitude(),
location.getLongitude());
String snippet = location.getLatitude() + "," + location.getLongitude();
Marker marker = mMap.addMarker(
new MarkerOptions().position(latlongzoom));
marker.setSnippet(snippet);
marker.setTitle(snippet);
// Center the map to the first marker
if (mLastLocation == null) {
mMap.moveCamera(CameraUpdateFactory.
newCameraPosition(CameraPosition.fromLatLngZoom(
new LatLng(location.getLatitude(), location.getLongitude()),
(float) 16.0)));
}
mLastLocation = location;
}
};
public void startActivityDetection(View v) {
if (!mActivityRecognitionClient.isConnected()) {
mActivityRecognitionClient.connect();
}
}
public void stopActivityDetection(View v) {
if (mActivityRecognitionClient.isConnected()) {
mActivityRecognitionClient.removeActivityUpdates(mActivityRecognitionPendingIntent);
mActivityRecognitionClient.disconnect();
}
}
private class ActivityRecognitionCallback implements ConnectionCallbacks, OnConnectionFailedListener {
#Override
public void onConnected(Bundle connectionHint) {
Log.v(LocationActivity.TAG, "Activity Recognition Client connected");
// Request activity updates
Intent intent = new Intent(LocationActivity.this,
ActivityRecognitionIntentService.class);
intent.setAction(LocationActivity.ACTION_ACTIVITY_RECOGNITION);
mActivityRecognitionPendingIntent = PendingIntent.getService(LocationActivity.this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
mActivityRecognitionClient.requestActivityUpdates(ACTIVITY_UPDATES_INTERVAL,
mActivityRecognitionPendingIntent);
}
#Override
public void onDisconnected() {
Log.v(LocationActivity.TAG, "Activity Recognition Client disconnected by the system");
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.v(LocationActivity.TAG,
"Activity Recognition Client connection failed " + result.getErrorCode());
}
};
private class GeoFenceCallback implements OnMapLongClickListener,
OnAddGeofencesResultListener, OnRemoveGeofencesResultListener {
#Override
public void onMapLongClick(LatLng point) {
Log.v(LocationActivity.TAG,
"onMapLongClick == " + point.latitude + "," + point.longitude);
CircleOptions circleOptions = new CircleOptions();
circleOptions.center(point).radius(GEOFENCE_RADIUS).strokeColor(
android.graphics.Color.BLUE).strokeWidth(2);
Circle circle = mMap.addCircle(circleOptions);
String key = Integer.toString(id);
id++;
mGeoFences.put(key, circle);
addGeoFences();
}
// Creates Geofence objects from all circles on the map and calls addGeofences API.
private void addGeoFences() {
List<Geofence> list = new ArrayList<Geofence>();
for (Map.Entry<String, Circle> entry : mGeoFences.entrySet()) {
Circle circle = entry.getValue();
Log.v(LocationActivity.TAG, "points == " +
circle.getCenter().latitude + "," +
circle.getCenter().longitude);
Geofence geofence = new Geofence.Builder()
.setRequestId(entry.getKey())
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT)
.setCircularRegion(circle.getCenter().latitude,
circle.getCenter().longitude,
(float) circle.getRadius())
.setExpirationDuration(Geofence.NEVER_EXPIRE).build();
list.add(geofence);
}
if (list.isEmpty()) {
return;
}
// Clear off all the currently triggering geo_fences before new fences
// are added.
for (Circle triggeringGeoFence : mTriggeringFences.values()) {
triggeringGeoFence.remove();
}
mTriggeringFences.clear();
Log.v(LocationActivity.TAG, "addingGeoFences size = " + list.size());
mLocationClient.addGeofences(list, getPendingIntent(), this);
}
private PendingIntent getPendingIntent() {
Intent intent = new Intent(ACTION_GEOFENCE);
intent.setComponent(new ComponentName(LocationActivity.this,
GeoFenceIntentReceiver.class));
return PendingIntent.getBroadcast(LocationActivity.this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
private void removeGeoFences() {
List<String> requestIdsForRemoval = new ArrayList<String>();
if (mGeoFences.isEmpty()) return;
for (Map.Entry<String, Circle> entry : mGeoFences.entrySet()) {
String requestId = entry.getKey();
Circle circle = entry.getValue();
if (circle != null) {
circle.remove();
id --;
Log.v(LocationActivity.TAG, "RemoveGeoFence requestId == " + requestId);
Circle triggeringCircle = mTriggeringFences.get(requestId);
if (triggeringCircle != null) {
triggeringCircle.remove();
}
requestIdsForRemoval.add(requestId);
}
}
mGeoFences.clear();
mTriggeringFences.clear();
mLocationClient.removeGeofences(requestIdsForRemoval, this);
}
#Override
public void onAddGeofencesResult(int statusCode,
String[] geofenceRequestIds) {
StringBuilder builder = new StringBuilder();
for (int i = 0 ; i < geofenceRequestIds.length - 1; ++i) {
builder.append(geofenceRequestIds[i]);
builder.append(",");
}
builder.append(geofenceRequestIds[geofenceRequestIds.length - 1]);
Log.v(LocationActivity.TAG, "Added Geofences == "
+ statusCodeToString(statusCode) + " " + builder.toString());
mGeoFenceStatus.setText("Added Geofences "
+ statusCodeToString(statusCode) + " " + builder.toString());
}
private String statusCodeToString(int statusCode) {
switch(statusCode) {
case LocationStatusCodes.SUCCESS :
return "SUCCESS";
case LocationStatusCodes.GEOFENCE_NOT_AVAILABLE :
return "GEOFENCE_NOT_AVAILABLE";
case LocationStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES :
return "GEOFENCE_TOO_MANY_GEOFENCES";
case LocationStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS :
return "GEOFENCE_TOO_MANY_PENDING_INTENTS";
case LocationStatusCodes.ERROR :
return "ERROR";
}
return "UNKNOWN";
}
#Override
public void onRemoveGeofencesByPendingIntentResult(int statusCode, PendingIntent pendingIntent) {
// Do nothing
}
#Override
public void onRemoveGeofencesByRequestIdsResult(int statusCode,
String[] geofenceRequestIds) {
StringBuilder builder = new StringBuilder();
for (int i = 0 ; i < geofenceRequestIds.length - 1; ++i) {
builder.append(geofenceRequestIds[i]);
builder.append(",");
}
builder.append(geofenceRequestIds[geofenceRequestIds.length - 1]);
Log.v(LocationActivity.TAG, "Removed Geofence " +
statusCodeToString(statusCode) + " " + builder.toString());
mGeoFenceStatus.setText("Removed Geofences request_ids = " +
builder.toString() + " " + statusCodeToString(statusCode));
}
};
// Triggered when startAcitivity method is called in GeoFenceIntentReceiver.
// Updates UI as geofences are entered/exited.
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// getIntent() should always return the most recent
setIntent(intent);
boolean receiverStarted =
intent.getBooleanExtra("RECEIVER_STARTED", false);
if (!receiverStarted) {
return;
}
Bundle bundle = intent.getParcelableExtra("geo_fences");
ArrayList<String> requestIds =
bundle.getStringArrayList("request_ids");
if (requestIds == null) {
Log.v(LocationActivity.TAG, "request_ids == null");
return;
}
int transition = intent.getIntExtra("transition", -2);
for (String requestId : requestIds) {
Log.v(LocationActivity.TAG, "Triggering Geo Fence requestId "
+ requestId);
if (transition == Geofence.GEOFENCE_TRANSITION_ENTER) {
Circle circle = mGeoFences.get(requestId);
if (circle == null) {
continue;
}
Log.v(LocationActivity.TAG, "triggering_geo_fences enter == "
+ requestId);
// Add a superimposed red circle when a geofence is entered and
// put the corresponding object in triggering_fences.
CircleOptions circleOptions = new CircleOptions();
circleOptions.center(circle.getCenter())
.radius(circle.getRadius())
.fillColor(Color.argb(100,100, 0, 0));
Circle newCircle = mMap.addCircle(circleOptions);
mTriggeringFences.put(requestId, newCircle);
} else if (transition == Geofence.GEOFENCE_TRANSITION_EXIT) {
Log.v(LocationActivity.TAG, "triggering_geo_fences exit == "
+ requestId);
Circle circle = mTriggeringFences.get(requestId);
if (circle == null) {
continue;
}
// Remove the superimposed red circle from the map and the
// corresponding Circle object from triggering_fences hash_map.
circle.remove();
mTriggeringFences.remove(requestId);
}
}
return;
}
}
2nd class
public class ActivityRecognitionIntentService extends IntentService {
public ActivityRecognitionIntentService() {
super("ActivityRecognitionIntentService");
}
public ActivityRecognitionIntentService(String name) {
super(name);
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent.getAction() != LocationActivity.ACTION_ACTIVITY_RECOGNITION) {
return;
}
if (ActivityRecognitionResult.hasResult(intent)) {
ActivityRecognitionResult result = ActivityRecognitionResult
.extractResult(intent);
DetectedActivity detectedActivity = result
.getMostProbableActivity();
int activityType = detectedActivity.getType();
Log.v(LocationActivity.TAG, "activity_type == " + activityType);
// Put the activity_type as an intent extra and send a broadcast.
Intent send_intent = new Intent(
LocationActivity.ACTION_ACTIVITY_RECOGNITION);
send_intent.putExtra("activity_type", activityType);
sendBroadcast(send_intent);
}
}
}
edited add the main part of the code
Please Modify your restartLocationClient() Method like this:
private void restartLocationClient() {
if (mLocationClient == null) {
mLocationClient = new LocationClient(this, mLocationCallback, mLocationCallback);
Log.v(LocationActivity.TAG, "Location Client connect");
if (!(mLocationClient.isConnected() || mLocationClient.isConnecting()))
{
mLocationClient.connect(); // Somehow it becomes connected here
return;
}
}
LocationRequest request = LocationRequest.create();
request.setInterval(LOCATION_UPDATES_INTERVAL);
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationClient.requestLocationUpdates(request, mLocationCallback);
}
It seems that your mLocationClient is null in this Method.
I hope this helps.
I know it's pretty late for this answer.
But for future reference, I'll post it anyways.
Basically, we have to understand the onConnect() method better. I find the explanation in this thread to be useful.
From there the workaround for this issue is pretty much straightforward.
Solution: restartLocationClient() is only called when mLocationClient.isConnected() returns true.
So, in your onResume method should look like the following:
if (mLocationClient.isConnected()) {
restartLocationClient();
}
Now it will work.