I have an Android video capture app but in Samsung devices I'm getting the error below.
I have tried to remove the startPreview() from the mRecordButton.click (which is the button to stop recording actually), no success.
What can I possibly do?
The error:
Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'android.hardware.camera2.CaptureRequest$Builder android.hardware.camera2.CameraDevice.createCaptureRequest(int)' on a null object reference
at com.jobconvo.www.newjcapp.CameraActivity.startPreview(CameraActivity.java:427)
at com.jobconvo.www.newjcapp.CameraActivity.access$800(CameraActivity.java:53)
at com.jobconvo.www.newjcapp.CameraActivity$5.onClick(CameraActivity.java:268)
at android.view.View.performClick(View.java:5716)
at android.widget.TextView.performClick(TextView.java:10926)
at android.view.View$PerformClick.run(View.java:22596)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
My Camera Activity code:
public class CameraActivity extends AppCompatActivity {
private static final int STATE_PREVIEW = 0;
private static final int STATE_WAIT_LOCK = 1;
private int mCaptureState = STATE_PREVIEW;
private TextureView mTextureView;
private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
setupCamera(width, height);
try {
connectCamera();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
};
private CameraDevice mCameraDevice;
private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(CameraDevice camera) {
mCameraDevice = camera;
mMediaRecorder = new MediaRecorder();
if (mIsRecording) {
try {
createVideoFileName();
} catch (IOException e) {
e.printStackTrace();
}
startRecord();
mMediaRecorder.start();
runOnUiThread(new Runnable() {
#Override
public void run() {
countDownTimer.start();
}
});
} else {
startPreview();
}
}
#Override
public void onDisconnected(CameraDevice camera) {
camera.close();
mCameraDevice = null;
}
#Override
public void onError(CameraDevice camera, int error) {
camera.close();
mCameraDevice = null;
}
};
private HandlerThread mBackgroundHandlerThread;
private Handler mBackgroundHandler;
private String mCameraId;
private Size mPreviewSize;
private Size mVideoSize;
private MediaRecorder mMediaRecorder;
private int mTotalRotation;
private CameraCaptureSession mPreviewCaptureSession;
private CameraCaptureSession.CaptureCallback mPreviewCaptureCallback = new
CameraCaptureSession.CaptureCallback() {
private void process(CaptureResult captureResult) {
switch (mCaptureState) {
case STATE_PREVIEW:
// Do nothing
break;
case STATE_WAIT_LOCK:
mCaptureState = STATE_PREVIEW;
Integer afState = captureResult.get(CaptureResult.CONTROL_AF_STATE);
if (afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
Toast.makeText(getApplicationContext(), "AF Locked!", Toast.LENGTH_SHORT).show();
}
break;
}
}
#Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
process(result);
}
};
private CameraCaptureSession mRecordCaptureSession;
private CameraCaptureSession.CaptureCallback mRecordCaptureCallback = new
CameraCaptureSession.CaptureCallback() {
private void process(CaptureResult captureResult) {
switch (mCaptureState) {
case STATE_PREVIEW:
// Do nothing
break;
case STATE_WAIT_LOCK:
mCaptureState = STATE_PREVIEW;
Integer afState = captureResult.get(CaptureResult.CONTROL_AF_STATE);
if (afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
Toast.makeText(getApplicationContext(), "AF Locked!", Toast.LENGTH_SHORT).show();
}
break;
}
}
#Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
process(result);
}
};
private CaptureRequest.Builder mCaptureRequestBuilder;
private Button mRecordButton;
private boolean mIsRecording = false;
private boolean mIsTimelapse = false;
private File mVideoFolder;
private String mVideoFileName;
private MainModel mainModel;
private static SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 0);
ORIENTATIONS.append(Surface.ROTATION_90, 90);
ORIENTATIONS.append(Surface.ROTATION_180, 180);
ORIENTATIONS.append(Surface.ROTATION_270, 270);
}
private static class CompareSizeByArea implements Comparator<Size> {
#Override
public int compare(Size lhs, Size rhs) {
return Long.signum((long) (lhs.getWidth() * lhs.getHeight()) -
(long) (rhs.getWidth() * rhs.getHeight()));
}
}
int questionId;
int questionAnswerTime;
String interviewId;
TextView showTimer;
private static String formatTime(int elapsed) {
int ss = elapsed % 60;
elapsed /= 60;
int min = elapsed % 60;
elapsed /= 60;
int hh = elapsed % 24;
return strzero(min) + ":" + strzero(ss);
}
private static String strzero(int n) {
if (n < 10)
return "0" + String.valueOf(n);
return String.valueOf(n);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
Fabric.with(this, new Crashlytics());
mainModel = (MainModel) getIntent().getSerializableExtra("serialized_data");
interviewId = mainModel.getInterviewID();
final ScriptQuestion getQuestion = mainModel.questions.get(0);
questionId = getQuestion.getQuestionId();
questionAnswerTime = getQuestion.getQuestionAnswerTime();
showTimer = (TextView) findViewById(R.id.chronometer);
mTextureView = (TextureView) findViewById(R.id.textureView);
mRecordButton = (Button) findViewById(R.id.videoButton);
mRecordButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
countDownTimer.cancel();
mIsRecording = false;
mIsTimelapse = false;
// Starting the preview prior to stopping recording which should hopefully
// resolve issues being seen in Samsung devices.
startPreview();
mMediaRecorder.stop();
mMediaRecorder.reset();
Intent mediaStoreUpdateIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaStoreUpdateIntent.setData(Uri.fromFile(new File(mVideoFileName)));
sendBroadcast(mediaStoreUpdateIntent);
goNext();
}
});
}
private CountDownTimer countDownTimer = new CountDownTimer(600000, 1000) {
public void onTick(long millisUntilFinished) {
// 600000 = 10 minutes
int restTime = questionAnswerTime * 60 - (600 - ((int) (millisUntilFinished) / 1000));
String tmpRest = formatTime(restTime);
showTimer.setText(tmpRest);
if (restTime < 1) {
onFinish();
}
}
public void onFinish() {
mRecordButton.performClick();
}
};
#Override
protected void onResume() {
super.onResume();
startBackgroundThread();
if (mTextureView.isAvailable()) {
setupCamera(mTextureView.getWidth(), mTextureView.getHeight());
} else {
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
}
mIsRecording = true;
}
#Override
protected void onPause() {
closeCamera();
stopBackgroundThread();
super.onPause();
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
View decorView = getWindow().getDecorView();
if (hasFocus) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
}
private void setupCamera(int width, int height) {
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) ==
CameraCharacteristics.LENS_FACING_BACK) {
continue;
}
StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
int deviceOrientation = getWindowManager().getDefaultDisplay().getRotation();
mTotalRotation = sensorToDeviceRotation(cameraCharacteristics, deviceOrientation);
boolean swapRotation = mTotalRotation == 90 || mTotalRotation == 270;
int rotatedWidth = width;
int rotatedHeight = height;
if (swapRotation) {
rotatedWidth = height;
rotatedHeight = width;
}
mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), rotatedWidth, rotatedHeight);
mVideoSize = chooseOptimalSize(map.getOutputSizes(MediaRecorder.class), rotatedWidth, rotatedHeight);
mCameraId = cameraId;
return;
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void connectCamera() throws CameraAccessException {
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
}
private void startRecord() {
try {
if(mIsRecording) {
setupMediaRecorder();
} else if(mIsTimelapse) {
setupTimelapse();
}
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
Surface recordSurface = mMediaRecorder.getSurface();
mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
mCaptureRequestBuilder.addTarget(previewSurface);
mCaptureRequestBuilder.addTarget(recordSurface);
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, recordSurface),
new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(CameraCaptureSession session) {
mRecordCaptureSession = session;
try {
mRecordCaptureSession.setRepeatingRequest(
mCaptureRequestBuilder.build(), null, null
);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(CameraCaptureSession session) {
//Log.d(TAG, "onConfigureFailed: startRecord");
}
}, null);
} catch (Exception e) {
e.printStackTrace();
}
}
private void startPreview() {
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
assert surfaceTexture != null;
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
try {
mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mCaptureRequestBuilder.addTarget(previewSurface);
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface),
new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(CameraCaptureSession session) {
//Log.d(TAG, "onConfigured: startPreview");
mPreviewCaptureSession = session;
try {
mPreviewCaptureSession.setRepeatingRequest(mCaptureRequestBuilder.build(),
null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(CameraCaptureSession session) {
//Log.d(TAG, "onConfigureFailed: startPreview");
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void closeCamera() {
if(mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
if(mMediaRecorder != null) {
mMediaRecorder.release();
mMediaRecorder = null;
}
}
private void startBackgroundThread() {
mBackgroundHandlerThread = new HandlerThread("Camera2VideoImage");
mBackgroundHandlerThread.start();
mBackgroundHandler = new Handler(mBackgroundHandlerThread.getLooper());
}
private void stopBackgroundThread() {
mBackgroundHandlerThread.quitSafely();
try {
mBackgroundHandlerThread.join();
mBackgroundHandlerThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static int sensorToDeviceRotation(CameraCharacteristics cameraCharacteristics, int deviceOrientation) {
int sensorOrienatation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
deviceOrientation = ORIENTATIONS.get(deviceOrientation);
return (sensorOrienatation + deviceOrientation + 360) % 360;
}
private static Size chooseOptimalSize(Size[] choices, int width, int height) {
List<Size> bigEnough = new ArrayList<Size>();
for(Size option : choices) {
if(option.getHeight() == option.getWidth() * height / width &&
option.getWidth() >= width && option.getHeight() >= height) {
bigEnough.add(option);
}
}
if(bigEnough.size() > 0) {
return Collections.min(bigEnough, new CompareSizeByArea());
} else {
return choices[0];
}
}
private File createVideoFileName() throws IOException {
File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "JobConvoVideos");
mVideoFolder = new File(mediaStorageDir, "JobConvoVideos");
if(!mVideoFolder.exists()) {
mVideoFolder.mkdirs();
}
String prepend = "android-" + interviewId + "-" + String.valueOf(questionId) + ".mp4";
File videoFile = new File(mediaStorageDir.getPath() + File.separator + prepend);
mVideoFileName = videoFile.getAbsolutePath();
return videoFile;
}
public static File getOutputMediaFile(String _interviewId, int qstId, Context _context){
String idInterview = _interviewId;
idInterview = "android-" + idInterview + "-" + String.valueOf(qstId) + ".mp4";
File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "JobConvoVideos");
_context.getExternalFilesDir("JobConvoVideos");
File f = new File(mediaStorageDir.getPath() + File.separator + idInterview);
return f;
}
private void setupMediaRecorder() throws IOException {
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setOutputFile(mVideoFileName);
mMediaRecorder.setVideoEncodingBitRate(1000000);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setOrientationHint(mTotalRotation);
mMediaRecorder.getMaxAmplitude();
mMediaRecorder.prepare();
}
private void setupTimelapse() throws IOException {
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_QVGA));
mMediaRecorder.setOutputFile(mVideoFileName);
mMediaRecorder.setCaptureRate(2);
mMediaRecorder.setOrientationHint(mTotalRotation);
mMediaRecorder.prepare();
}
private void goNext() {
finish();
Intent goUpload = new Intent(this, VideoUploadActivity.class);
goUpload.putExtra("serialized_data", mainModel);
startActivity(goUpload);
}
#Override
public void onBackPressed() {
Toast.makeText(getApplicationContext(), R.string.getBack, Toast.LENGTH_LONG).show();
}
}
I added a try catch here in which the app has shown a great improvement. Nonetheless it still crashes sometimes. Not very often.
mRecordButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
countDownTimer.cancel();
mIsRecording = false;
mIsTimelapse = false;
// Starting the preview prior to stopping recording which should hopefully
// resolve issues being seen in Samsung devices.
try {
startPreview();
mMediaRecorder.stop();
mMediaRecorder.reset();
} catch (Exception e) {
e.printStackTrace();
}
Intent mediaStoreUpdateIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaStoreUpdateIntent.setData(Uri.fromFile(new File(mVideoFileName)));
sendBroadcast(mediaStoreUpdateIntent);
goNext();
}
});
Related
i made a googlemap app where my markers are displyed.
the problem is when there no internet, the app is crashing. The code under onResume does not solve the problem.
also i want to refresh the map or markers each second on the map.
if you have any ideas please i am here to learn from all of you.
here is my MapActivity code :
public class MapActivity extends AppCompatActivity implements OnMapReadyCallback
{
private static final String TAG = "MapActivity";
#Bind(R.id.back)
View back;
#Bind(R.id.zoom_in)
View zoom_in;
#Bind(R.id.zoom_out)
View zoom_out;
#Bind(R.id.updatetimer)
TextView updatetimer;
#Bind(R.id.autozoom)
ImageView autozoom;
#Bind(R.id.showtails)
ImageView showtails;
#Bind(R.id.geofences)
ImageView showGeofences;
#Bind(R.id.map_layer)
ImageView map_layer_icon;
private GoogleMap map;
#Bind(R.id.content_layout)
View content_layout;
#Bind(R.id.loading_layout)
View loading_layout;
#Bind(R.id.nodata_layout)
View nodata_layout;
private Timer timer;
private int autoZoomedTimes = 0;// dėl bugo osmdroid library, zoom'inam du kartus ir paskui po refresh'o nebe, nes greičiausiai user'is bus pakeitęs zoom'ą
private HashMap<Integer, Marker> deviceIdMarkers;
private HashMap<String, Device> markerIdDevices;
private HashMap<Integer, Polyline> deviceIdPolyline;
private HashMap<Integer, LatLng> deviceIdLastLatLng;
// private HashMap<Integer, Marker> deviceIdSmallMarkerInfo;
private long lastRefreshTime;
boolean isAutoZoomEnabled = true;
boolean isShowTitlesEnabled;
boolean isShowTailsEnabled = true;
boolean isShowGeofencesEnabled = true;
private String stopTime;
private AsyncTask downloadingAsync;
private boolean isRefreshLoced = false;
ApiInterface.GetGeofencesResult geofencesResult;
ArrayList<PolygonWithName> polygonsWithDetails = new ArrayList<>();
float previousZoomLevel = 0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
ButterKnife.bind(this);
deviceIdMarkers = new HashMap<>();
markerIdDevices = new HashMap<>();
deviceIdPolyline = new HashMap<>();
deviceIdLastLatLng = new HashMap<>();
// deviceIdSmallMarkerInfo = new HashMap<>();
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
protected void onResume()
{
super.onResume();
timer = new Timer();
timer.schedule(new TimerTask()
{
#Override
public void run()
{
runOnUiThread(new Runnable()
{
#Override
public void run()
{
float timeleft = 10 - Math.round(System.currentTimeMillis() - lastRefreshTime) / 1000f;
if (timeleft < 0)
timeleft = 0;
updatetimer.setText(String.format("%.0f", timeleft));
if (System.currentTimeMillis() - lastRefreshTime >= 10 * 1000)
if (map != null)
refresh();
}
});
}
}, 0, 1000);
}
#Override
protected void onPause()
{
super.onPause();
try
{
timer.cancel();
timer.purge();
downloadingAsync.cancel(true);
} catch (Exception e)
{
e.printStackTrace();
}
}
private void refresh()
{
if (isRefreshLoced)
return;
isRefreshLoced = true;
lastRefreshTime = System.currentTimeMillis();
final String api_key = (String) DataSaver.getInstance(this).load("api_key");
API.getApiInterface(this).getDevices(api_key, getResources().getString(R.string.lang), new Callback<ArrayList<ApiInterface.GetDevicesItem>>()
{
#Override
public void success(final ArrayList<ApiInterface.GetDevicesItem> getDevicesItems, Response response)
{
Log.d(TAG, "success: loaded devices array");
final ArrayList<Device> allDevices = new ArrayList<>();
if (getDevicesItems != null)
for (ApiInterface.GetDevicesItem item : getDevicesItems)
allDevices.addAll(item.items);
API.getApiInterface(MapActivity.this).getFieldsDataForEditing(api_key, getResources().getString(R.string.lang), 1, new Callback<ApiInterface.GetFieldsDataForEditingResult>()
{
#Override
public void success(final ApiInterface.GetFieldsDataForEditingResult getFieldsDataForEditingResult, Response response)
{
Log.d(TAG, "success: loaded icons");
downloadingAsync = new AsyncTask<Void, Void, Void>()
{
ArrayList<MarkerOptions> markers;
ArrayList<Integer> deviceIds;
#Override
protected Void doInBackground(Void... params)
{
// add markers
int dp100 = Utils.dpToPx(MapActivity.this, 50);
markers = new ArrayList<>();
deviceIds = new ArrayList<>();
if (getFieldsDataForEditingResult == null || getFieldsDataForEditingResult.device_icons == null)
return null;
for (Device item : allDevices)
{
if (isCancelled())
break;
if (item.device_data.active == 1)
{
// ieškom ikonos masyve
DeviceIcon mapIcon = null;
for (DeviceIcon icon : getFieldsDataForEditingResult.device_icons)
if (item.device_data.icon_id == icon.id)
mapIcon = icon;
String server_base = (String) DataSaver.getInstance(MapActivity.this).load("server_base");
try
{
Log.d("MapActivity", "DOWNLOADING BITMAP: " + server_base + mapIcon.path);
Bitmap bmp = BitmapFactory.decodeStream(new URL(server_base + mapIcon.path).openConnection().getInputStream());
int srcWidth = bmp.getWidth();
int srcHeight = bmp.getHeight();
int maxWidth = Utils.dpToPx(MapActivity.this, mapIcon.width);
int maxHeight = Utils.dpToPx(MapActivity.this, mapIcon.height);
float ratio = Math.min((float) maxWidth / (float) srcWidth, (float) maxHeight / (float) srcHeight);
int dstWidth = (int) (srcWidth * ratio);
int dstHeight = (int) (srcHeight * ratio);
bmp = bmp.createScaledBitmap(bmp, dp100, dp100, true);
// marker
MarkerOptions m = new MarkerOptions();
m.position(new LatLng(item.lat, item.lng));
// marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
// marker.setIcon(new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bmp, dstWidth, dstHeight, true)));
m.icon(BitmapDescriptorFactory.fromBitmap(Bitmap.createScaledBitmap(bmp, dstWidth, dstHeight, true)));
// info window
// MapMarkerInfoWindow infoWindow = new MapMarkerInfoWindow(MapActivity.this, item, R.layout.layout_map_infowindow, map);
// marker.setInfoWindow(infoWindow);
markers.add(m);
deviceIds.add(item.id);
} catch (OutOfMemoryError outOfMemoryError)
{
Toast.makeText(MapActivity.this, "Out of memory! Too many devices are selected to be displayed", Toast.LENGTH_LONG).show();
} catch (Exception e)
{
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void aVoid)
{
ArrayList<GeoPoint> points = new ArrayList<>();
if (autoZoomedTimes < 1)
{
new Handler().postDelayed(new Runnable()
{
#Override
public void run()
{
runOnUiThread(new Runnable()
{
#Override
public void run()
{
if (markers.size() > 1)
{
try
{
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (MarkerOptions item : markers)
builder.include(item.getPosition());
LatLngBounds bounds = builder.build();
// int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, Utils.dpToPx(MapActivity.this, 50));
map.animateCamera(cu);
} catch (Exception e)
{
}
} else if (markers.size() > 0)
{
map.moveCamera(CameraUpdateFactory.newLatLngZoom(markers.get(0).getPosition(), 15));
}
autoZoomedTimes++;
}
});
}
}, 50);
} else if (isAutoZoomEnabled)
{
if (markers.size() > 1)
{
try
{
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (MarkerOptions item : markers)
builder.include(item.getPosition());
LatLngBounds bounds = builder.build();
// int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, Utils.dpToPx(MapActivity.this, 50));
map.animateCamera(cu);
} catch (Exception e)
{
}
} else if (markers.size() > 0)
{
map.moveCamera(CameraUpdateFactory.newLatLngZoom(markers.get(0).getPosition(), 15));
}
autoZoomedTimes++;
}
Log.d(TAG, "onPostExecute: icons downloaded and added to map, total markers: " + markers.size());
loading_layout.setVisibility(View.GONE);
if (markers.size() != 0)
content_layout.setVisibility(View.VISIBLE);
else
nodata_layout.setVisibility(View.VISIBLE);
for (int i = 0; i < markers.size(); i++)
{
MarkerOptions options = markers.get(i);
int deviceId = deviceIds.get(i);
Marker m;
Polyline polyline;
if (deviceIdMarkers.containsKey(deviceId))
{
Log.d("aa", "moving to" + options.getPosition());
deviceIdMarkers.get(deviceId).setPosition(new LatLng(options.getPosition().latitude, options.getPosition().longitude));
m = deviceIdMarkers.get(deviceId);
polyline = deviceIdPolyline.get(deviceId);
} else
{
Log.d("aa", "putting new");
m = map.addMarker(options);
deviceIdMarkers.put(deviceId, m);
polyline = map.addPolyline(new PolylineOptions());
deviceIdPolyline.put(deviceId, polyline);
}
Device thatonedevice = null;
for (Device device : allDevices)
if (device.id == deviceId)
thatonedevice = device;
markerIdDevices.put(m.getId(), thatonedevice);
// update marker rotation based on driving direction
if (thatonedevice != null && deviceIdLastLatLng.containsKey(deviceId))
{
double dirLat = thatonedevice.lat - deviceIdLastLatLng.get(deviceId).latitude;
double dirLng = thatonedevice.lng - deviceIdLastLatLng.get(deviceId).longitude;
m.setRotation((float) Math.toDegrees(Math.atan2(dirLng, dirLat)));
}
deviceIdLastLatLng.put(deviceId, new LatLng(thatonedevice.lat, thatonedevice.lng));
List<LatLng> polylinePoints = new ArrayList<>();
for (TailItem item : thatonedevice.tail)
polylinePoints.add(new LatLng(Double.valueOf(item.lat), Double.valueOf(item.lng)));
polyline.setPoints(polylinePoints);
polyline.setWidth(Utils.dpToPx(MapActivity.this, 2));
polyline.setColor(Color.parseColor(thatonedevice.device_data.tail_color));
}
// else
map.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter()
{
#Override
public View getInfoWindow(Marker marker)
{
return null;
}
#Override
public View getInfoContents(final Marker marker)
{
synchronized (this)
{
}
final Device device = markerIdDevices.get(marker.getId());
if (device != null)
{
View view = getLayoutInflater().inflate(R.layout.layout_map_infowindow, null);
view.bringToFront();
view.findViewById(R.id.close).setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
marker.hideInfoWindow();
}
});
TextView device_name = (TextView) view.findViewById(R.id.device_name);
device_name.setText(device.name);
TextView altitude = (TextView) view.findViewById(R.id.altitude);
altitude.setText(String.valueOf(device.altitude) + " " + device.unit_of_altitude);
TextView time = (TextView) view.findViewById(R.id.time);
time.setText(device.time);
TextView stopTimeView = (TextView) view.findViewById(R.id.stopTime);
stopTimeView.setText(stopTime);
TextView speed = (TextView) view.findViewById(R.id.speed);
speed.setText(device.speed + " " + device.distance_unit_hour);
TextView address = (TextView) view.findViewById(R.id.address);
address.setText(device.address);
final ArrayList<Sensor> showableSensors = new ArrayList<>();
for (Sensor item : device.sensors)
if (item.show_in_popup > 0)
showableSensors.add(item);
ListView sensors_list = (ListView) view.findViewById(R.id.sensors_list);
sensors_list.setAdapter(new AwesomeAdapter<Sensor>(MapActivity.this)
{
#Override
public int getCount()
{
return showableSensors.size();
}
#NonNull
#Override
public View getView(int position, View convertView, #NonNull ViewGroup parent)
{
if (convertView == null)
convertView = getLayoutInflater().inflate(R.layout.adapter_map_sensorslist, null);
Sensor item = showableSensors.get(position);
TextView name = (TextView) convertView.findViewById(R.id.name);
name.setText(item.name);
TextView value = (TextView) convertView.findViewById(R.id.value);
value.setText(item.value);
return convertView;
}
});
List<Address> addresses;
try
{
addresses = new Geocoder(MapActivity.this).getFromLocation(device.lat, device.lng, 1);
if (addresses.size() > 0)
address.setText(addresses.get(0).getAddressLine(0));
} catch (IOException e)
{
e.printStackTrace();
}
return view;
}
return null;
}
});
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()
{
#Override
public boolean onMarkerClick(final Marker marker)
{
int px = Utils.dpToPx(MapActivity.this, 300);
map.setPadding(0, px, 0, 0);
stopTime = "...";
final Device device = markerIdDevices.get(marker.getId());
if (device != null)
{
API.getApiInterface(MapActivity.this).deviceStopTime((String) DataSaver.getInstance(MapActivity.this).load("api_key"), "en", device.id, new Callback<ApiInterface.DeviceStopTimeResult>()
{
#Override
public void success(ApiInterface.DeviceStopTimeResult result, Response response)
{
stopTime = result.time;
marker.showInfoWindow();
}
#Override
public void failure(RetrofitError retrofitError)
{
Toast.makeText(MapActivity.this, R.string.errorHappened, Toast.LENGTH_SHORT).show();
}
});
}
return false;
}
});
map.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener()
{
#Override
public void onInfoWindowClick(Marker marker)
{
marker.hideInfoWindow();
}
});
map.setOnInfoWindowCloseListener(new GoogleMap.OnInfoWindowCloseListener()
{
#Override
public void onInfoWindowClose(Marker marker)
{
map.setPadding(0, 0, 0, 0);
}
});
// updateSmallMarkerData(allDevices);
isRefreshLoced = false;
}
}.execute();
}
#Override
public void failure(RetrofitError retrofitError)
{
Toast.makeText(MapActivity.this, R.string.errorHappened, Toast.LENGTH_SHORT).show();
isRefreshLoced = false;
}
});
}
#Override
public void failure(RetrofitError retrofitError)
{
Toast.makeText(MapActivity.this, R.string.errorHappened, Toast.LENGTH_SHORT).show();
isRefreshLoced = false;
}
});
}
#Override
public void onMapReady(GoogleMap googleMap)
{
map = googleMap;
refresh();
}
this MapActivity is slow to load, could you teach me a way to make it goes faster?
Best regard :)
waiting for your propositions.
PS: i have removed some functions to make the code look short but i kept the most important in is case.
For the crashing issue
create a class
public class NetWorkChecker {
static NetworkInfo wifi, mobile;
public static Boolean check(Context c) {
ConnectivityManager cm = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
try {
wifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
mobile = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
} catch (Exception e) {
e.printStackTrace();
}
if (wifi != null && wifi.isConnected() && wifi.isAvailable()) {
return true;
} else if (mobile != null && mobile.isAvailable() && mobile.isConnected()) {
return true;
} else {
//Toast.makeText(c, "No Network Connection", Toast.LENGTH_SHORT).show();
// ((Activity) c).finish();
displayMobileDataSettingsDialog(c,"No Network Connection","No Network Connection");
return false;
}
}
public static AlertDialog displayMobileDataSettingsDialog(final Context context, String title, String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(title);
builder.setMessage(message);
builder.setCancelable(false);
builder.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
context.startActivity(intent);
}
});
builder.show();
return builder.create();
}
}
to check if the devise have an active internet connection
call
if (!NetWorkChecker.check(this)){
////do your refres
}
2020-04-22 16:14:49.759 1809-1809/? E/servicemanager: Could not find android.hardware.power.IPower/default in the VINTF manifest.
This keeps popping up. Am coding a camera, that when a button is clicked, an image is cropped.
Here is a custom view I am adding to a fragment.
public class DrawView extends View {
Point[] points = new Point[4];
/**
* point1 and point 3 are of same group and same as point 2 and point4
*/
int groupId = -1;
private ArrayList<ColorBall> colorballs = new ArrayList<>();
private int mStrokeColor = Color.parseColor("#AADB1255");
private int mFillColor = Color.parseColor("#55DB1255");
private Rect mCropRect = new Rect();
// array that holds the balls
private int balID = 0;
// variable to know what ball is being dragged
Paint paint;
public DrawView(Context context) {
this(context, null);
}
public DrawView(Context context, AttributeSet attrs) {
this(context, attrs, -1);
}
public DrawView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
paint = new Paint();
setFocusable(true); // necessary for getting the touch events
}
private void initRectangle(int X, int Y) {
//initialize rectangle.
points[0] = new Point();
points[0].x = X - 200;
points[0].y = Y - 100;
points[1] = new Point();
points[1].x = X;
points[1].y = Y + 30;
points[2] = new Point();
points[2].x = X + 30;
points[2].y = Y + 30;
points[3] = new Point();
points[3].x = X + 30;
points[3].y = Y;
balID = 2;
groupId = 1;
// declare each ball with the ColorBall class
for (int i = 0; i < points.length; i++) {
colorballs.add(new ColorBall(getContext(), R.drawable.gray_circle, points[i], i));
}
}
// the method that draws the balls
#Override
protected void onDraw(Canvas canvas) {
if(points[3]==null) {
//point4 null when view first create
initRectangle(getWidth() / 2, getHeight() / 2);
}
int left, top, right, bottom;
left = points[0].x;
top = points[0].y;
right = points[0].x;
bottom = points[0].y;
for (int i = 1; i < points.length; i++) {
left = left > points[i].x ? points[i].x : left;
top = top > points[i].y ? points[i].y : top;
right = right < points[i].x ? points[i].x : right;
bottom = bottom < points[i].y ? points[i].y : bottom;
}
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(5);
//draw stroke
paint.setStyle(Paint.Style.STROKE);
paint.setColor(mStrokeColor);
paint.setStrokeWidth(2);
mCropRect.left = left + colorballs.get(0).getWidthOfBall() / 2;
mCropRect.top = top + colorballs.get(0).getWidthOfBall() / 2;
mCropRect.right = right + colorballs.get(2).getWidthOfBall() / 2;
mCropRect.bottom = bottom + colorballs.get(3).getWidthOfBall() / 2;
canvas.drawRect(mCropRect, paint);
//fill the rectangle
paint.setStyle(Paint.Style.FILL);
paint.setColor(mFillColor);
paint.setStrokeWidth(0);
canvas.drawRect(mCropRect, paint);
// draw the balls on the canvas
paint.setColor(Color.RED);
paint.setTextSize(18);
paint.setStrokeWidth(0);
for (int i =0; i < colorballs.size(); i ++) {
ColorBall ball = colorballs.get(i);
canvas.drawBitmap(ball.getBitmap(), ball.getX(), ball.getY(),
paint);
canvas.drawText("" + (i+1), ball.getX(), ball.getY(), paint);
}
}
// events when touching the screen
public boolean onTouchEvent(MotionEvent event) {
int eventAction = event.getAction();
int X = (int) event.getX();
int Y = (int) event.getY();
switch (eventAction) {
case MotionEvent.ACTION_DOWN: // touch down so check if the finger is on
// a ball
if (points[0] == null) {
initRectangle(X, Y);
} else {
//resize rectangle
balID = -1;
groupId = -1;
for (int i = colorballs.size()-1; i>=0; i--) {
ColorBall ball = colorballs.get(i);
// check if inside the bounds of the ball (circle)
// get the center for the ball
int centerX = ball.getX() + ball.getWidthOfBall();
int centerY = ball.getY() + ball.getHeightOfBall();
paint.setColor(Color.CYAN);
// calculate the radius from the touch to the center of the
// ball
double radCircle = Math
.sqrt((double) (((centerX - X) * (centerX - X)) + (centerY - Y)
* (centerY - Y)));
if (radCircle < ball.getWidthOfBall()) {
balID = ball.getID();
if (balID == 1 || balID == 3) {
groupId = 2;
} else {
groupId = 1;
}
invalidate();
break;
}
invalidate();
}
}
break;
case MotionEvent.ACTION_MOVE: // touch drag with the ball
if (balID > -1) {
// move the balls the same as the finger
colorballs.get(balID).setX(X);
colorballs.get(balID).setY(Y);
paint.setColor(Color.CYAN);
if (groupId == 1) {
colorballs.get(1).setX(colorballs.get(0).getX());
colorballs.get(1).setY(colorballs.get(2).getY());
colorballs.get(3).setX(colorballs.get(2).getX());
colorballs.get(3).setY(colorballs.get(0).getY());
} else {
colorballs.get(0).setX(colorballs.get(1).getX());
colorballs.get(0).setY(colorballs.get(3).getY());
colorballs.get(2).setX(colorballs.get(3).getX());
colorballs.get(2).setY(colorballs.get(1).getY());
}
invalidate();
}
break;
case MotionEvent.ACTION_UP:
// touch drop - just do things here after dropping
break;
}
// redraw the canvas
invalidate();
return true;
}
public Drawable doTheCrop(Bitmap sourceBitmap) throws IOException {
//Bitmap sourceBitmap = null;
//Drawable backgroundDrawable = getBackground();
/*
if (backgroundDrawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) backgroundDrawable;
if(bitmapDrawable.getBitmap() != null) {
sourceBitmap = bitmapDrawable.getBitmap();
}
}*/
//source bitmap was scaled, you should calculate the rate
float widthRate = ((float) sourceBitmap.getWidth()) / getWidth();
float heightRate = ((float) sourceBitmap.getHeight()) / getHeight();
//crop the source bitmap with rate value
int left = (int) (mCropRect.left * widthRate);
int top = (int) (mCropRect.top * heightRate);
int right = (int) (mCropRect.right * widthRate);
int bottom = (int) (mCropRect.bottom * heightRate);
Bitmap croppedBitmap = Bitmap.createBitmap(sourceBitmap, left, top, right - left, bottom - top);
Drawable drawable = new BitmapDrawable(getResources(), croppedBitmap);
return drawable;
/*
setContentView(R.layout.fragment_dashboard);
Button btn = (Button)findViewById(R.id.capture);
if (btn == null){
System.out.println("NULL");
}
try{
btn.setText("HI");
}
catch (Exception e){
}
//setBackground(drawable);*/
//savebitmap(croppedBitmap);
}
private File savebitmap(Bitmap bmp) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 60, bytes);
File f = new File(Environment.getExternalStorageDirectory()
+ "/" + "testimage.jpg");
Toast.makeText(getContext(), "YUP", Toast.LENGTH_LONG).show();
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
return f;
}
public static class ColorBall {
Bitmap bitmap;
Context mContext;
Point point;
int id;
public ColorBall(Context context, int resourceId, Point point, int id) {
this.id = id;
bitmap = BitmapFactory.decodeResource(context.getResources(),
resourceId);
mContext = context;
this.point = point;
}
public int getWidthOfBall() {
return bitmap.getWidth();
}
public int getHeightOfBall() {
return bitmap.getHeight();
}
public Bitmap getBitmap() {
return bitmap;
}
public int getX() {
return point.x;
}
public int getY() {
return point.y;
}
public int getID() {
return id;
}
public void setX(int x) {
point.x = x;
}
public void setY(int y) {
point.y = y;
}
}
}
Here is the fragment that I have added a camera do, basically the main part of the application that I am working on.
public class DashboardFragment extends Fragment {
private DashboardViewModel dashboardViewModel;
//All my constants
private DrawView mDrawView;
private Drawable imgDraw;
private TextureView txtView;
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, 180);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
private String cameraID;
private String pathway;
CameraDevice cameraDevice;
CameraCaptureSession cameraCaptureSession;
CaptureRequest captureRequest;
CaptureRequest.Builder captureRequestBuilder;
private Size imageDimensions;
private ImageReader imageReader;
private File file;
Handler mBackgroundHandler;
HandlerThread mBackgroundThread;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
dashboardViewModel =
ViewModelProviders.of(this).get(DashboardViewModel.class);
View root = inflater.inflate(R.layout.fragment_dashboard, container, false);
try{
txtView = (TextureView)root.findViewById(R.id.textureView);
txtView.setSurfaceTextureListener(textureListener);
mDrawView = root.findViewById(draw_view);
Button cap = (Button)root.findViewById(R.id.capture);
cap.setClickable(true);
cap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
Log.i("HOLA","HOLA");
takePicture();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
});
}
catch (Exception e){
Log.i("HI",e.toString());
}
/*
txtView = (TextureView)root.findViewById(R.id.textureView);
txtView.setSurfaceTextureListener(textureListener);
mDrawView = root.findViewById(R.id.draw_view);
Button cap = (Button)root.findViewById(R.id.capture);
cap.setClickable(true);
cap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
Log.i("HOLA","HOLA");
takePicture();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
});*/
return root;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults){
if (requestCode == 101){
if (grantResults[0] == PackageManager.PERMISSION_DENIED){
Toast.makeText(getActivity().getApplicationContext(), "Permission is required",Toast.LENGTH_LONG);
}
}
}
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
try {
openCamera();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
};
private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(#NonNull CameraDevice camera) {
cameraDevice = camera;
try {
createCameraPreview();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onDisconnected(#NonNull CameraDevice cameraDevice) {
cameraDevice.close();
}
#Override
public void onError(#NonNull CameraDevice cameraDevice, int i) {
cameraDevice.close();
cameraDevice = null;
}
};
private void createCameraPreview() throws CameraAccessException {
SurfaceTexture texture = txtView.getSurfaceTexture(); //?
texture.setDefaultBufferSize(imageDimensions.getWidth(), imageDimensions.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 session) {
if (cameraDevice == null){
return;
}
cameraCaptureSession = session;
try {
updatePreview();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(getActivity().getApplicationContext(), "CONFIGURATION", Toast.LENGTH_LONG);
}
}, null);
}
private void updatePreview() throws CameraAccessException {
if (cameraDevice == null){
return;
}
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
}
private void openCamera() throws CameraAccessException {
CameraManager manager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
cameraID = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraID);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
imageDimensions = map.getOutputSizes(SurfaceTexture.class)[0];
if (ActivityCompat.checkSelfPermission(getActivity().getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(getActivity().getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 101);
return;
}
manager.openCamera(cameraID, stateCallback, null);
}
private void takePicture() throws CameraAccessException {
if (cameraDevice == null) {
Log.i("NOt working", "hi");
return;
}
CameraManager manager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
Size[] jpegSizes = null;
jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
int width = 640;
int height = 480;
if (jpegSizes != null && jpegSizes.length > 0) {
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
final ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List<Surface> outputSurfaces = new ArrayList<>(2);
outputSurfaces.add(reader.getSurface());
outputSurfaces.add(new Surface(txtView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
Long tsLong = System.currentTimeMillis() / 1000;
String ts = tsLong.toString();
file = new File(Environment.getExternalStorageDirectory() + "/" + ts + ".jpg");
pathway = Environment.getExternalStorageDirectory() + "/" + ts + ".jpg";
//cameraDevice.close();
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader imageReader) {
Image image = null;
//image = reader.acquireLatestImage();
image = reader.acquireNextImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes , 0, bytes.length);
try {
Drawable back = mDrawView.doTheCrop(bitmap);
Button btn = (Button)getView().findViewById(R.id.capture);
btn.setBackground(back);
} catch (IOException e) {
e.printStackTrace();
}
/*
try {
save(bytes);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (image != null){
image.close();
}
}*/
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback(){
#Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result){
super.onCaptureCompleted(session, request, result);
try {
createCameraPreview();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
};
cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession session) {
try {
session.capture(captureBuilder.build(), captureListener, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
}
}, mBackgroundHandler);
}
private void save (byte[] bytes) throws IOException {
OutputStream outputStream = null;
outputStream = new FileOutputStream(file);
outputStream.write(bytes);
Toast.makeText(getActivity().getApplicationContext(),pathway,Toast.LENGTH_LONG).show();
outputStream.close();
imgDraw = Drawable.createFromPath(pathway);
//mDrawView.doTheCrop(imgDraw);
}
#Override
public void onResume(){
super.onResume();
startBackgroundThread();
if (txtView.isAvailable()){
try {
openCamera();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
else{
txtView.setSurfaceTextureListener(textureListener);
}
}
private void startBackgroundThread() {
mBackgroundThread = new HandlerThread("Camera Background");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
protected void stopBackgroundThread() throws InterruptedException{
mBackgroundThread.quitSafely();
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
}
#Override
public void onPause(){
try {
stopBackgroundThread();
} catch (InterruptedException e) {
e.printStackTrace();
}
super.onPause();
}
}
Here is the xml file for that fragment.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.dashboard.DashboardFragment">
<TextureView
android:id = "#+id/textureView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.PeavlerDevelopment.OpinionMinion.ui.dashboard.DrawView
android:id="#+id/draw_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<Button
android:id="#+id/capture"
android:layout_width="100dp"
android:layout_height="200dp"
android:clickable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"></Button>
</androidx.constraintlayout.widget.ConstraintLayout>
The problem seems to lie somewhere in the doCrop method of the DrawView class.
If there is anything else that would help make the problem more clear, let me know! I will gladly share the github repo with you.
Thank you.
As you can see in Android Design Documenation the VINTF stands for Vendor Interface and its a Manifest structure to aggregate data form the device. That specific log means that your manifest is missing something like this:
<hal>
<name>android.hardware.power</name>
<transport>hwbinder</transport>
<version>1.1</version>
<interface>
<name>IPower</name>
<instance>default</instance>
</interface>
</hal>
which basically is hardware power information.
I think it's not related to what you are trying to do, but I need more info than that log.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I can't seem to figure out what I am doing wrong here. Can anyone please help? I have altered the code a few times but unless I completely remove the OnResume, which I need, the code always terminates the program.
Code:
public class CameraFragment extends Fragment {
private TextureView textureView;
private HandlerThread mBackgroundHandlerThread;
private Handler mBackgroundHandler;
private String mCameraId;
private Size mPreviewSize;
public static CameraFragment newInstance() {
return new CameraFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout. fragment_camera, container, false);
return rootView;
}
private static final int REQUEST_CAMERA_PERMISSION_RESULT = 0;
private TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
setupCamera(width, height);
connectCamera();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
};
private CameraDevice mCameraDevice;
private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(CameraDevice camera) {
mCameraDevice = camera;
startPreview();
//Toast.makeText(getApplicationContext(), "Camera connected!", Toast.LENGTH_LONG).show();
}
#Override
public void onDisconnected( CameraDevice camera) {
camera.close();
mCameraDevice = null;
}
#Override
public void onError( CameraDevice camera, int error) {
camera.close();
mCameraDevice = null;
}
};
#Override
public void onResume() {
super.onResume();
startBackgroundThread();
if (textureView.isAvailable()) {
setupCamera(textureView.getWidth(), textureView.getHeight());
connectCamera();
} else {
textureView.setSurfaceTextureListener(surfaceTextureListener);
}
}
#Override
public void onPause() {
closeCamera();
stopBackgroundThread();
super.onPause();
}
private void closeCamera() {
if(mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
}
private void stopBackgroundThread() {
mBackgroundHandlerThread.quitSafely();
try {
mBackgroundHandlerThread.join();
mBackgroundHandlerThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private CaptureRequest.Builder mCaptureRequestBuilder;
private static SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 0);
ORIENTATIONS.append(Surface.ROTATION_90, 90);
ORIENTATIONS.append(Surface.ROTATION_180, 180);
ORIENTATIONS.append(Surface.ROTATION_270, 270);
}
private static class CompareSizeByArea implements Comparator<Size> {
#Override
public int compare(Size lhs, Size rhs){
return Long.signum((long) lhs.getWidth() * lhs.getHeight() /
(long) rhs.getWidth() * rhs.getHeight());
}
}
private static int sensorToDeviceRotation(CameraCharacteristics cameraCharacteristics, int deviceOrientation){
int sensorOrientation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
deviceOrientation = ORIENTATIONS.get(deviceOrientation);
return(sensorOrientation + deviceOrientation + 360) % 360;
}
public void onWindowFocusChanged (boolean hasFocus) {
super.getActivity().onWindowFocusChanged(hasFocus);
View decorView = getActivity().getWindow().getDecorView();
if(hasFocus){
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
}
private void setupCamera(int width, int height) {
CameraManager cameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
try {
assert cameraManager != null;
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
if(cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) ==
CameraCharacteristics.LENS_FACING_FRONT){
continue;
}
StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
int deviceOrientation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
int totalRotation = sensorToDeviceRotation(cameraCharacteristics, deviceOrientation);
boolean swapRotation = totalRotation == 90 || totalRotation == 270;
int rotatedWidth = width;
int rotatedHeight = height;
if (swapRotation){
rotatedWidth = height;
rotatedHeight = width;
}
if (map != null) {
mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), rotatedWidth, rotatedHeight);
}
mCameraId = cameraId;
return;
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void connectCamera() {
CameraManager cameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
try {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_GRANTED) {
assert cameraManager != null;
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
} else {
if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
Toast.makeText(getActivity(), "This app requires access to camera", Toast.LENGTH_LONG).show();
}
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION_RESULT);
}
} else {
assert cameraManager != null;
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
}
}catch(CameraAccessException e){
e.printStackTrace();
}
}
private void startBackgroundThread() {
mBackgroundHandlerThread = new HandlerThread("Camera Background");
mBackgroundHandlerThread.start();
mBackgroundHandler = new Handler(mBackgroundHandlerThread.getLooper());
}
private void startPreview() {
SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
try {
mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mCaptureRequestBuilder.addTarget(previewSurface);
mCameraDevice.createCaptureSession(Collections.singletonList(previewSurface),
new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession session) {
try {
session.setRepeatingRequest(mCaptureRequestBuilder.build(),
null, mBackgroundHandler);
} catch (CameraAccessException e){
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession session) {
Toast.makeText(getActivity(), "Unable to connect to camera", Toast.LENGTH_LONG).show();
}
}, null);
} catch (CameraAccessException e){
e.printStackTrace();
}
}
private static Size chooseOptimalSize(Size[] choices, int width, int height) {
List<Size> bigEnough = new ArrayList<Size>();
for(Size option : choices){
if(option.getHeight() == option.getWidth() * height/width &&
option.getWidth() >= width && option.getHeight() >= height) {
bigEnough.add(option);
}
}
if(bigEnough.size() > 0){
return Collections.min(bigEnough, (Comparator<? super Size>) new CompareSizeByArea());
} else {
return choices[0];
}
}
}
Terminal:
01-30 16:04:10.295 23701-23701/com.example.patrick.wz
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.patrick.wz, PID: 23701
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.view.TextureView.setSurfaceTextureListener(android.view.TextureView$SurfaceTextureListener)'
on a null object reference
at
com.example.patrick.wz.Fragments.CameraFragment.onResume(CameraFragment.java:124)
at android.support.v4.app.Fragment.performResume(Fragment.java:2401)
at
android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1465)
at
android.support.v4.app.FragmentManagerImpl.performPendingDeferredStart(FragmentManager.java:1228)
at
android.support.v4.app.FragmentManagerImpl.startPendingDeferredFragments(FragmentManager.java:1845)
at
android.support.v4.app.FragmentManagerImpl.doPendingDeferredStart(FragmentManager.java:2689)
at
android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2205)
at
android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:651)
at
android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:145)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1236)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1084)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614)
at android.view.View.measure(View.java:21045)
at
android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:934)
at
android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:973)
at android.view.View.measure(View.java:21045)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6459)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at
android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
at android.view.View.measure(View.java:21045)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6459)
at
android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:21045)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6459)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:21045)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6459)
at
android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:21045)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6459)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:849)
at android.view.View.measure(View.java:21045)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2576)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1635)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1886)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1515)
at
android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7091)
at
android.view.Choreographer$CallbackRecord.run(Choreographer.java:927)
at android.view.Choreographer.doCallbacks(Choreographer.java:702)
at android.view.Choreographer.doFrame(Choreographer.java:638)
at
android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:913)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
onResume method
textureView doesn't seem to be initialized,
you have to do something like this
textureView = new TextureView(this);
if (textureView.isAvailable()) {
setupCamera(textureView.getWidth(), textureView.getHeight());
connectCamera();
} else {
textureView.setSurfaceTextureListener(surfaceTextureListener);
}
I am trying to build a simple app that launches the camera app and allows me to take a picture and save it to the device but I keep getting this error.
java.lang.RuntimeException: Fail to connect to camera service
MainActivity
public class MainActivity extends AppCompatActivity
{
private static final String TAG = MainActivity.class.getName();
Preview preview;
private Camera camera;
private int cameraId;
#Override
protected void onCreate(Bundle savedInstanceState)
{
final Camera.PictureCallback jpegCallback;
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
preview = new Preview(this, (SurfaceView)findViewById(R.id.surfaceView));
preview.setLayoutParams(new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT));
((FrameLayout) findViewById(R.id.activity_main)).addView(preview);
preview.setKeepScreenOn(true);
jpegCallback = new Camera.PictureCallback()
{
public void onPictureTaken(final byte[] data,
final Camera camera)
{
new SaveImageTask().execute(data);
resetCam();
Log.d(TAG, "onPictureTaken - jpeg");
}
};
preview.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
if(camera != null)
{
camera.takePicture(null,
// ShutterCallback shutter
null,
// PictureCallback raw,
null,
// PictureCallback postview,
jpegCallback); // PictureCallback jpeg);
}
}
});
}
#Override
protected void onResume()
{
super.onResume();
getCamera(CameraInfo.CAMERA_FACING_BACK);
if(camera != null)
{
camera.startPreview();
preview.setCamera(camera);
}
}
#Override
protected void onPause()
{
if(camera != null)
{
camera.stopPreview();
preview.setCamera(null);
camera.release();
camera = null;
}
super.onPause();
}
private void getCamera(final int desiredCamera)
{
if(!getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA))
{
Toast.makeText(this, "No camera on this device", Toast.LENGTH_LONG)
.show();
}
else
{
cameraId = findCamera(desiredCamera);
if(cameraId < 0)
{
Toast.makeText(this, "Camera no found.",
Toast.LENGTH_LONG).show();
}
else
{
Log.d(TAG, Integer.toString(cameraId));
camera = Camera.open(cameraId);
camera.setDisplayOrientation(90);
}
}
}
private int findCamera(final int desiredCamera)
{
final int numberOfCameras;
int cameraId;
numberOfCameras = Camera.getNumberOfCameras();
cameraId = -1;
for(int i = 0; i < numberOfCameras; i++)
{
final CameraInfo info;
info = new CameraInfo();
Camera.getCameraInfo(i, info);
if(info.facing == desiredCamera)
{
Log.d(TAG, "Camera found");
cameraId = i;
break;
}
}
return (cameraId);
}
private void resetCam()
{
camera.startPreview();
preview.setCamera(camera);
}
private void refreshGallery(final File file)
{
final Intent mediaScanIntent;
mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(Uri.fromFile(file));
sendBroadcast(mediaScanIntent);
}
private class SaveImageTask
extends AsyncTask<byte[], Void, Void>
{
#Override
protected Void doInBackground(final byte[]... data)
{
FileOutputStream outStream;
final File sdCard;
final File dir;
final String fileName;
final File outFile;
sdCard = Environment.getExternalStorageDirectory();
dir = new File (sdCard.getAbsolutePath() + "/camtest");
dir.mkdirs();
fileName = String.format("%d.jpg", System.currentTimeMillis());
outFile = new File(dir, fileName);
outStream = null;
try
{
outStream = new FileOutputStream(outFile);
outStream.write(data[0]);
outStream.flush();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length + " to " + outFile.getAbsolutePath());
refreshGallery(outFile);
}
catch(final FileNotFoundException ex)
{
Log.e(TAG, "File not found", ex);
}
catch(final IOException ex)
{
Log.e(TAG, "IOException", ex);
}
finally
{
try
{
if(outStream != null)
{
outStream.close();
}
}
catch(final IOException ex)
{
Log.e(TAG, "IOException", ex);
}
}
return null;
}
}
}
Preview
class Preview
extends ViewGroup
implements Callback
{
private final String TAG = Preview.class.getName();
private SurfaceView surfaceView;
private SurfaceHolder holder;
private Camera.Size previewSize;
private List<Camera.Size> supportedPreviewSizes;
private Camera camera;
Preview(final Context context,
final SurfaceView sv)
{
super(context);
surfaceView = sv;
holder = surfaceView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void setCamera(Camera camera)
{
this.camera = camera;
if(this.camera != null)
{
final Camera.Parameters params;
final List<String> focusModes;
supportedPreviewSizes = this.camera.getParameters().getSupportedPreviewSizes();
requestLayout();
params = this.camera.getParameters();
focusModes = params.getSupportedFocusModes();
if(focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO))
{
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
this.camera.setParameters(params);
}
}
}
#Override
protected void onMeasure(final int widthMeasureSpec,
final int heightMeasureSpec)
{
// We purposely disregard child measurements because act as a
// wrapper to a SurfaceView that centers the camera preview instead
// of stretching it.
final int width;
final int height;
width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
if(supportedPreviewSizes != null)
{
previewSize = getOptimalPreviewSize(supportedPreviewSizes, width, height);
}
}
#Override
protected void onLayout(boolean changed,
int l,
int t,
int r,
int b)
{
if (changed && getChildCount() > 0)
{
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (previewSize != null)
{
previewWidth = previewSize.width;
previewHeight = previewSize.height;
}
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth)
{
final int scaledChildWidth = previewWidth * height / previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
}
else
{
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height - scaledChildHeight) / 2,
width, (height + scaledChildHeight) / 2);
}
}
}
public void surfaceCreated(SurfaceHolder holder)
{
// The Surface has been created, acquire the camera and tell it where
// to draw.
try
{
if(camera != null)
{
camera.setPreviewDisplay(holder);
}
}
catch (IOException exception)
{
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
public void surfaceDestroyed(SurfaceHolder holder)
{
// Surface will be destroyed when we return, so stop the preview.
if(camera != null)
{
camera.stopPreview();
}
}
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes,
int w,
int h)
{
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Camera.Size size : sizes)
{
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null)
{
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes)
{
if (Math.abs(size.height - targetHeight) < minDiff)
{
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
public void surfaceChanged(SurfaceHolder holder,
int format,
int width,
int height)
{
if(camera != null)
{
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(previewSize.width, previewSize.height);
requestLayout();
camera.setParameters(parameters);
camera.startPreview();
}
}
the problem is simple, the media player is blocking the UI when implementing the source from remote server. i used a sync prepare for the initialize the media-player, but its block the UI when reset the media player.
here i written a code using thread, it helps a lot but need a clean solution.
public class QuranPlayerAct extends Activity implements DownloadMusicLstn,SeekBar.OnSeekBarChangeListener, OnClickListener,
MediaPlayer.OnPreparedListener, OnCompletionListener,
PlayerBtnClickedLstn, Runnable {
private static final int PLAY_FROM_LOCAL = 234;
private static final int PLAY_FROM_SERVER = 321;
private static final String TAG = "SongsListAct";
private static final int PAUSED = 756;
private static final int STARTED = 554;
private static final int STOPED = 386;
private static final int CLOSED = 453;
private TextView downloadEsplasedTV;
private RelativeLayout playerRetLay;
private ListView musicLst;
private ProgressBar dwnPrgV;
private ImageView playImgV;
private SeekBar songProgressBar;
private TextView songTitleLabel;
private TextView songCurrentDurationLabel;
private TextView songTotalDurationLabel;
private MediaPlayer mp;
private Utilities utils;
private Handler handler;
private boolean stopDownload;
private RelativeLayout downloadRetLay;
private ArrayList<String> musicFiles;
private ImageButton closeImgV;
private TextView downloadTitle;
private long currentDuration;
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
if (mPrepared) {
long totalDuration = mp.getDuration();
currentDuration = mp.getCurrentPosition();
songTotalDurationLabel.setText(""
+ utils.milliSecondsToTimer(totalDuration));
songCurrentDurationLabel.setText(""
+ utils.milliSecondsToTimer(currentDuration));
int progress = (int) (utils.getProgressPercentage(
currentDuration, totalDuration));
songProgressBar.setProgress(progress);
}
handler.postDelayed(this, 100);
}
};
private TextView downloadTotalTV;
private TextView downloadPercentageTV;
private ImageView stopImgV;
private ImageButton closeDownloadImgV;
private int fileSize;
private boolean mPrepared;
private ProgressBar songsLoadingPB;
private String url;
private String fName;
private boolean stopped;
private int plLoc;
private int track_no;
private int state;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_quran_player);
// setActionBar();
setActionBar2();
getRefs();
handler = new Handler();
initMediaPlayer();
playerRetLay.setVisibility(View.GONE);
// updateList();
createAppDirectory();
Thread t = new Thread(this);
t.start();
}
private void setActionBar2() {
final ActionBar bar = getActionBar();
bar.setDisplayShowHomeEnabled(false);
bar.setDisplayShowCustomEnabled(true);
bar.setDisplayShowTitleEnabled(false);
bar.setCustomView(R.layout.player_actionbar_lay);
}
/*
* private void setActionBar() { final ActionBar bar = getActionBar();
*
* bar.setDisplayShowHomeEnabled(false);
* bar.setDisplayShowCustomEnabled(true);
* bar.setDisplayShowTitleEnabled(false);
* bar.setCustomView(R.layout.player_actionbar_lay);
*
* TextView tv = (TextView) bar.getCustomView().findViewById(
* R.id.action_bar_title);
*
* try { tv.setTypeface(Typeface .createFromAsset(getAssets(),
* "DANUBE__.TTF")); } catch (Exception e) { e.printStackTrace(); } }
*/
#Override
public void onResume() {
super.onResume();
setVisiblilityToPlayerAndUI(false);
updateProgressBar();
if(state==CLOSED)playerRetLay.setVisibility(View.GONE);
}
#Override
public void onPause() {
super.onPause();
l("Activity paused");
stopDownload = true;
setVisiblilityToPlayerAndUI(false);
handler.removeCallbacks(mUpdateTimeTask);
if (mp != null)
switch (state) {
case STARTED:
mp.pause();
playImgV.setImageResource(R.drawable.play_img);
break;
}
}
private void getRefs() {
musicLst = (ListView) findViewById(R.id.musLst_lstV);
playerRetLay = (RelativeLayout) findViewById(R.id.musLst_player_retLay);
dwnPrgV = (ProgressBar) findViewById(R.id.musLst_down_progbarV);
downloadRetLay = (RelativeLayout) findViewById(R.id.musLst_dwn_retLay);
playImgV = (ImageView) findViewById(R.id.musLst_ply_btn);
songProgressBar = (SeekBar) findViewById(R.id.musLst_seek_bar);
songTitleLabel = (TextView) findViewById(R.id.musLst_mus_det_txt);
songCurrentDurationLabel = (TextView) findViewById(R.id.time_esplased_TV);
songTotalDurationLabel = (TextView) findViewById(R.id.total_time_TV);
closeImgV = (ImageButton) findViewById(R.id.musLst_close_btn);
downloadTitle = (TextView) findViewById(R.id.musLst_down_title_TV);
downloadEsplasedTV = (TextView) findViewById(R.id.time_esplased_TV22);
downloadTotalTV = (TextView) findViewById(R.id.total_time_TV2);
downloadPercentageTV = (TextView) findViewById(R.id.total_percentage);
stopImgV = (ImageView) findViewById(R.id.musLst_stop_btn);
closeDownloadImgV = (ImageButton) findViewById(R.id.close_down_btn);
songsLoadingPB = (ProgressBar) findViewById(R.id.songs_load_progressbar);
}
#Override
public void run() {
if (!isNetworkAvailable()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(QuranPlayerAct.this,
"No Internet Connection Available",
Toast.LENGTH_LONG).show();
}
});
return;
}
MusicAppUtils appUtils = new MusicAppUtils();
String jsn = appUtils
.getDataFromUrl(MusicAppCommons.HTTP_AIMANSANGAM_COM_LISTFILES_PHP);
if (jsn == null)
return;
jsn = jsn.replace(",]", "]");
musicFiles = appUtils.parseMusicFilesJson(jsn);
updateList();
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager
.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
private void createAppDirectory() {
if (MusicAppCommons
.checkFileExist(MusicAppCommons.AIMANSANGAM_MUSIC_DIR)) {
Log.i(TAG, "app directory already exist");
return;
}
File dir = new File(MusicAppCommons.AIMANSANGAM_MUSIC_DIR);
if (dir.mkdirs())
Log.i(TAG, "app directory created");
}
private void setVisiblilityToPlayerAndUI(boolean b) {
if (b) {
songsLoadingPB.setVisibility(View.VISIBLE);
downloadRetLay.setVisibility(View.VISIBLE);
// playerRetLay.setVisibility(View.VISIBLE);
} else {
songsLoadingPB.setVisibility(View.GONE);
downloadRetLay.setVisibility(View.GONE);
// playerRetLay.setVisibility(View.GONE);
}
}
private void initMediaPlayer() {
utils = new Utilities();
mp = new MediaPlayer();
mp.setOnCompletionListener(this);
songProgressBar.setOnSeekBarChangeListener(this);
playImgV.setOnClickListener(this);
closeDownloadImgV.setOnClickListener(this);
closeImgV.setOnClickListener(this);
stopImgV.setOnClickListener(this);
}
private void resetTimeLabel() {
runOnUiThread(new Runnable() {
#Override
public void run() {
songTotalDurationLabel.setText("..");
songCurrentDurationLabel.setText("..");
}
});
}
public void updateProgressBar() {
handler.removeCallbacks(mUpdateTimeTask);
handler.postDelayed(mUpdateTimeTask, 100);
}
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(mUpdateTimeTask);
if (mp != null)
mp.release();
}
public void updateList() {
l("called update list");
if (musicFiles == null)
return;
updateMusicListView(MusicLstAdapter.MUSIC_NOT_DOWNLOADING);
}
private void updateMusicListView(int state) {
final MusicLstAdapter lstAdapter = new MusicLstAdapter(this,
musicFiles, this, state, this);
runOnUiThread(new Runnable() {
#Override
public void run() {
musicLst.setAdapter(lstAdapter);
lstAdapter.notifyDataSetChanged();
}
});
}
#Override
public void onClick(View v) {
if (v == closeDownloadImgV) {
downloadRetLay.setVisibility(View.GONE);
stopDownload = true;
Toast.makeText(this, "Download canceled", Toast.LENGTH_SHORT)
.show();
} else if (v == playImgV) {
if (stopped)
new PlayerThread();
if (mp.isPlaying()) {
if (mp != null) {
state = PAUSED;
mp.pause();
l("pause");
playImgV.setImageResource(R.drawable.play_img);
}
} else {
if (mp != null) {
state = STARTED;
mp.start();
l("start");
playImgV.setImageResource(R.drawable.pause_img);
}
}
} else if (v == closeImgV) {
l("close clicked");
state = CLOSED;
playerRetLay.setVisibility(View.GONE);
handler.removeCallbacks(mUpdateTimeTask);
mp.stop();
mPrepared = false;
new Thread(new Runnable() {
#Override
public void run() {
mp.reset();
}
}).start();
} else if (v == stopImgV) {
l("stop clicked");
state = STOPED;
handler.removeCallbacks(mUpdateTimeTask);
mp.stop();
resetTimeLabel();
playImgV.setImageResource(R.drawable.play_img);
stopped = true;
mPrepared = false;
}
}
// --------************************************************************************
#Override
public void setSize(final int fileSize) {
handler.post(new Runnable() {
#Override
public void run() {
dwnPrgV.setMax(fileSize);
QuranPlayerAct.this.fileSize = fileSize;
float size = (float) fileSize / 1048576;
DecimalFormat format = new DecimalFormat("#.##");
downloadTotalTV.setText(format.format(size) + " MB");
downloadPercentageTV.setText("0 %");
}
});
}
#Override
public void onProgressUpdate(final long total) {
handler.post(new Runnable() {
#Override
public void run() {
dwnPrgV.setProgress((int) total);
float size = (float) total / 1048576;
DecimalFormat format = new DecimalFormat("#.##");
downloadEsplasedTV.setText(format.format(size) + " MB");
float l = total / (float) fileSize * 100;
int round = Math.round(l);
downloadPercentageTV.setText(round + " %");
}
});
}
#Override
public void finished() {
handler.post(new Runnable() {
#Override
public void run() {
downloadRetLay.setVisibility(View.GONE);
}
});
updateMusicListView(MusicLstAdapter.MUSIC_NOT_DOWNLOADING);
}
#Override
public void onDownloadSuccess(boolean success) {
if (success) {
} else {
}
}
#Override
public boolean isStopDownload() {
return stopDownload;
}
#Override
public void downloadStarted(final String fName) {
stopDownload = false;
handler.post(new Runnable() {
#Override
public void run() {
downloadTitle.setText(fName);
downloadRetLay.setVisibility(View.VISIBLE);
}
});
updateMusicListView(MusicLstAdapter.MUSIC_DOWNLOADING);
}
// ----------------*****************************************************************************
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromTouch) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(mUpdateTimeTask);
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(mUpdateTimeTask);
int totalDuration = mp.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(),
totalDuration);
mp.seekTo(currentPosition);
updateProgressBar();
}
#Override
public void onPrepared(MediaPlayer mp) {
l("onprepared");
mPrepared = true;
mp.start();
state = STARTED;
playImgV.setImageResource(R.drawable.pause_img);
}
private void l(String str) {
Log.i(TAG, str);
}
// ---------------------***************************************************************************
private class PlayerThread extends Thread {
public PlayerThread() {
start();
}
#Override
public void run() {
try {
stopped = false;
mPrepared = false;
resetTimeLabel();
mp.reset();
mp.setDataSource(url);
if (plLoc == PLAY_FROM_SERVER) {
mp.prepareAsync();
mp.setOnPreparedListener(QuranPlayerAct.this);
updatePlayerImg(R.drawable.play_img);
} else {
mp.prepare();
mp.start();
mPrepared = true;
state = STARTED;
updatePlayerImg(R.drawable.pause_img);
}
updatePlayerUI();
updateProgressBar();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void updatePlayerUI() {
runOnUiThread(new Runnable() {
#Override
public void run() {
songTitleLabel.setText(fName);
songProgressBar.setProgress(0);
songProgressBar.setMax(100);
}
});
}
}
private void updatePlayerImg(final int playImg) {
runOnUiThread(new Runnable() {
#Override
public void run() {
playImgV.setImageResource(playImg);
}
});
}
// ------------------------------
#Override
public void onCompletion(MediaPlayer mp) {
track_no++;
if (track_no > musicFiles.size() - 1) {
track_no = 0;
}
playerRetLay.setVisibility(View.VISIBLE);
fName = musicFiles.get(track_no);
String filePath = MusicAppCommons.AIMANSANGAM_MUSIC_DIR + "/" + fName;
if (MusicAppCommons.checkFileExist(filePath)) {
url = filePath;
plLoc = PLAY_FROM_LOCAL;
} else {
url = MusicAppCommons.HTTP_AIMANSANGAM_COM_QURAN_FILES + fName;
url = url.replace(" ", "%20");
plLoc = PLAY_FROM_SERVER;
}
new PlayerThread();
}
#Override
public void clickedOnPlayBtn(int val) {
this.track_no = val;
l("song clicked");
playerRetLay.setVisibility(View.VISIBLE);
fName = musicFiles.get(val);
String filePath = MusicAppCommons.AIMANSANGAM_MUSIC_DIR + "/" + fName;
if (MusicAppCommons.checkFileExist(filePath)) {
url = filePath;
plLoc = PLAY_FROM_LOCAL;
} else {
url = MusicAppCommons.HTTP_AIMANSANGAM_COM_QURAN_FILES + fName;
url = url.replace(" ", "%20");
plLoc = PLAY_FROM_SERVER;
}
new PlayerThread();
}
}