How to solve activity not starting from a service? - android

I have a background service which is an accessibility service (don't think it makes a difference). I want to launch a new activity from this service. I have tried using this suggested solution:
Intent dialogIntent = new Intent(this, ScreenshotActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(dialogIntent);
However, this does not seem to work. My logcat gives this output but the activity does not launch:
020-03-20 20:54:02.824 22977-22977/com.xx.xx I/Timeline: Timeline: Activity_launch_request time:19482980
My service and activity work properly independently. But not in this situation. The point from where I am making this call is reached as well. The device I am using for testing is running Android 9.
Edit: Main service code:
public class MyAccessibility extends AccessibilityService {
public static MyAccessibility instance;
#Override
public void onCreate() {
super.onCreate();
Log.i("myLog", "create accessibility");
}
#Override
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
Log.i("myLog", "Event");
if (instance == null) {
Log.i("myLog", "Instance set to not null");
instance = this;
}
}
#Override
public void onInterrupt() {
}
#Override
protected void onServiceConnected() {
super.onServiceConnected();
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
info.notificationTimeout = 100;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
this.setServiceInfo(info);
Toast t = Toast.makeText(getApplicationContext(), "Accessibility Service is connected now", Toast.LENGTH_SHORT);
t.show();
System.out.println("Accessibility was connected!");
instance = this;
}
public void takeSS(){
Intent dialogIntent = new Intent(this, ScreenshotActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(dialogIntent);
}
There are some other methods which uses dispatchGesture. That is why I have a static reference to this and I can access these methods from elsewhere. The screenshot activity uses media projection to take the screenshot and use the image:
public class ScreenshotActivity extends Activity {
private static final int REQUEST_MEDIA_PROJECTION = 1;
private static final String TAG = "ScreenshotActivity";
private MediaProjectionManager mProjectionManager;
private MediaProjection mMediaProjection = null;
private VirtualDisplay mVirtualDisplay;
private ImageReader mImageReader;
private static final int MAX_IMAGE_BUFFER = 10;
private int counter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screenshot_dummy);
counter = 0;
OrientationChangedListener mOrientationChangedListener = new OrientationChangedListener(this);
mOrientationChangedListener.enable();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mProjectionManager = (MediaProjectionManager)getSystemService(MEDIA_PROJECTION_SERVICE);
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);
}
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
super.onActivityResult(requestCode, resultCode, resultData);
if (requestCode == REQUEST_MEDIA_PROJECTION) {
String message;
if (resultCode != Activity.RESULT_OK) {
message = "Media Projection Declined";
mMediaProjection = null;
} else {
message = "Media Projection Accepted";
mMediaProjection = mProjectionManager.getMediaProjection(resultCode, resultData);
attachImageCaptureOverlay();
}
Toast toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
toast.show();
}
}
private class OrientationChangedListener extends OrientationEventListener {
int mLastOrientation = -1;
OrientationChangedListener(Context context) {
super(context);
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public void onOrientationChanged(int orientation) {
final int screenOrientation = getWindowManager().getDefaultDisplay().getRotation();
if (mVirtualDisplay == null) return;
if (mLastOrientation == screenOrientation) return;
mLastOrientation = screenOrientation;
detachImageCaptureOverlay();
attachImageCaptureOverlay();
}
}
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage();
if (image == null || image.getPlanes().length <= 0) return;
final Image.Plane plane = image.getPlanes()[0];
final int rowPadding = plane.getRowStride() - plane.getPixelStride() * image.getWidth();
final int bitmapWidth = image.getWidth() + rowPadding / plane.getPixelStride();
final Bitmap tempBitmap = Bitmap.createBitmap(bitmapWidth, image.getHeight(), Bitmap.Config.ARGB_8888);
tempBitmap.copyPixelsFromBuffer(plane.getBuffer());
Rect cropRect = image.getCropRect();
final Bitmap bitmap = Bitmap.createBitmap(tempBitmap, cropRect.left, cropRect.top, cropRect.width(), cropRect.height());
//Do something with the bitmap
image.close();
}
};
#RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private void attachImageCaptureOverlay() {
if (mMediaProjection == null) return;
final DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
mImageReader = ImageReader.newInstance(metrics.widthPixels, metrics.heightPixels, PixelFormat.RGBA_8888, MAX_IMAGE_BUFFER);
mVirtualDisplay = mMediaProjection.createVirtualDisplay("ScreenCaptureTest",
metrics.widthPixels, metrics.heightPixels, metrics.densityDpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mImageReader.getSurface(), null, null);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void detachImageCaptureOverlay() {
mVirtualDisplay.release();
mImageReader.close();
}
}

You can't start activity from background since Android Oreo.
One workaround is to call startForeground(true) when your service starts, then add sticky Notification to your service with appropriate action(starting your desired activity via PendingIntent).

Related

passing byte Array image into next Activity

My app consist Image Capture Face Recognition what i need to implement is converting the byte Array image into bitmap , and pass the bitmap to next Activity, The next Activity will receive the bitmap and show it in an image-view , than convert the bitmap into base 64.
I Don't know how to implement above task into my existing codes.
So when image is captured it shows, once click to save button pass the image to next activity and again convert the bitmap into base64.
FaceTrackerAcivity.java
public final class FaceTrackerActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "FaceTracker";
private CameraSource mCameraSource = null;
private CameraSourcePreview mPreview;
private GraphicOverlay mGraphicOverlay;
private ImageView btnCapture;
private ImageView btnChangeCamera;
private ImageView btnCancel;
private ImageView btnSave;
private FrameLayout frmResult;
private ImageView imgPicture;
Bitmap bmp;
private static final int RC_HANDLE_GMS = 9001;
// permission request codes need to be < 256
private static final int RC_HANDLE_CAMERA_PERM = 2;
private static final int RC_HANDLE_WRITE_EXTERNAL_STORAGE_PERM = 3;
private int cameraId = CameraSource.CAMERA_FACING_BACK;
Intent x;
//==============================================================================================
// Activity Methods
//==============================================================================================
/**
* Initializes the UI and initiates the creation of a face detector.
*/
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
mPreview = (CameraSourcePreview) findViewById(R.id.preview);
mGraphicOverlay = (GraphicOverlay) findViewById(R.id.faceOverlay);
btnCapture = (ImageView) findViewById(R.id.btn_capture);
btnChangeCamera = (ImageView) findViewById(R.id.btn_change_camera);
btnCancel = (ImageView) findViewById(R.id.btn_cancel);
btnSave = (ImageView) findViewById(R.id.btn_save);
frmResult = (FrameLayout) findViewById(R.id.frm_capture_result);
imgPicture = (ImageView) findViewById(R.id.img_capture_result);
boolean hasPermissionCamera = (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED);
if (!hasPermissionCamera) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, RC_HANDLE_CAMERA_PERM);
} else {
boolean hasPermissionWriteStorage = (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
if (!hasPermissionWriteStorage) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_HANDLE_WRITE_EXTERNAL_STORAGE_PERM);
} else {
createCameraSource(cameraId);
}
}
btnCapture.setOnClickListener(this);
btnChangeCamera.setOnClickListener(this);
}
private void createCameraSource(int cameraId) {
Context context = getApplicationContext();
FaceDetector detector = new FaceDetector.Builder(context)
.setClassificationType(FaceDetector.ALL_CLASSIFICATIONS)
.build();
detector.setProcessor(
new MultiProcessor.Builder<>(new GraphicFaceTrackerFactory())
.build());
if (!detector.isOperational()) {
Log.w(TAG, "Face detector dependencies are not yet available.");
}
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
mCameraSource = new CameraSource.Builder(context, detector)
.setRequestedPreviewSize(metrics.heightPixels, metrics.widthPixels)
.setFacing(cameraId)
.setAutoFocusEnabled(true)
.setRequestedFps(30.0f)
.build();
}
#Override
protected void onResume() {
super.onResume();
startCameraSource();
}
#Override
protected void onPause() {
super.onPause();
mPreview.stop();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mCameraSource != null) {
mCameraSource.release();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case RC_HANDLE_CAMERA_PERM: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
finish();
startActivity(getIntent());
}
break;
}
case RC_HANDLE_WRITE_EXTERNAL_STORAGE_PERM: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
finish();
startActivity(getIntent());
}
break;
}
}
}
private void startCameraSource() {
// check that the device has play services available.
int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
getApplicationContext());
if (code != ConnectionResult.SUCCESS) {
Dialog dlg = GoogleApiAvailability.getInstance().getErrorDialog(this, code, RC_HANDLE_GMS);
dlg.show();
}
if (mCameraSource != null) {
try {
mPreview.start(mCameraSource, mGraphicOverlay);
} catch (IOException e) {
Log.e(TAG, "Unable to start camera source.", e);
mCameraSource.release();
mCameraSource = null;
}
}
}
#Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.btn_capture) {
Toast.makeText(this, "capture", Toast.LENGTH_SHORT).show();
mCameraSource.takePicture(null, new CameraSource.PictureCallback() {
#Override
public void onPictureTaken(final byte[] bytes) {
int orientation = Exif.getOrientation(bytes);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
switch (orientation) {
case 90:
bmp = Utils.rotateImage(bmp, 90);
break;
case 180:
bmp = Utils.rotateImage(bmp, 180);
break;
case 270:
bmp = Utils.rotateImage(bmp, 270);
break;
}
if (cameraId == CameraSource.CAMERA_FACING_FRONT) {
bmp = Utils.flip(bmp, Constants.FLIP_HORIZONTAL);
}
if (bmp != null) {
frmResult.setVisibility(View.VISIBLE);
imgPicture.setImageBitmap(bmp);
btnCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
frmResult.setVisibility(View.GONE);
}
});
btnSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SavePhotoTask savePhotoTask = new SavePhotoTask();
savePhotoTask.execute(bytes);
}
});
}
}
});
} else if (id == R.id.btn_change_camera) {
mCameraSource.release();
mCameraSource = null;
cameraId = cameraId == CameraSource.CAMERA_FACING_BACK ? CameraSource.CAMERA_FACING_FRONT : CameraSource.CAMERA_FACING_BACK;
createCameraSource(cameraId);
startCameraSource();
}
}
private class GraphicFaceTrackerFactory implements MultiProcessor.Factory<Face> {
#Override
public Tracker<Face> create(Face face) {
return new GraphicFaceTracker(mGraphicOverlay);
}
}
private class GraphicFaceTracker extends Tracker<Face> {
private GraphicOverlay mOverlay;
private FaceGraphic mFaceGraphic;
GraphicFaceTracker(GraphicOverlay overlay) {
mOverlay = overlay;
mFaceGraphic = new FaceGraphic(overlay);
}
#Override
public void onNewItem(int faceId, Face item) {
mFaceGraphic.setId(faceId);
}
#Override
public void onUpdate(FaceDetector.Detections<Face> detectionResults, Face face) {
mOverlay.add(mFaceGraphic);
mFaceGraphic.updateFace(face);
}
#Override
public void onMissing(FaceDetector.Detections<Face> detectionResults) {
mOverlay.remove(mFaceGraphic);
}
#Override
public void onDone() {
mOverlay.remove(mFaceGraphic);
}
}
class SavePhotoTask extends AsyncTask<byte[], String, String> {
#Override
protected String doInBackground(byte[]... data) {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "TRACKER_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
try {
File photo = File.createTempFile(imageFileName, ".jpg", storageDir);
FileOutputStream fos = new FileOutputStream(photo.getPath());
fos.write(data[0]);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}}
NEXT.java
public class NEXT extends AppCompatActivity {
ImageView y;
Intent intent;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.next);
y = (ImageView) findViewById(R.id.myimage);
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("key");
y.setImageBitmap(bitmap);
}}
Putin large data (>1Mo) can produce android.os.TransactionTooLargeException, ref :
The Binder transaction buffer has a limited fixed size, currently
1Mb, which is shared by all transactions in progress for the
process. Consequently this exception can be thrown when there are many
transactions in progress even when most of the individual transactions
are of moderate size.
The best way is to create a class and put your image into it, you can then access to it from any activity

screen shot using media projection not perfoming any action

hi everyone i have a sample screenshot project from (#commonsware) using media project to perform a screen shot in any screen (running in foreground service mode with notification)
however its not taking any picture and just beeping on button click
also my approach is to change the directory but don't know how
i need to change it cause i want to load all images in a recyclerview inside app
any help will appreciated
here's the whole service code:
public class ScreenShotService extends Service {
private static final int NOTIFY_ID = 9906;
static final String EXTRA_RESULT_CODE = "resultCode";
static final String EXTRA_RESULT_INTENT = "resultIntent";
static final String ACTION_RECORD = BuildConfig.APPLICATION_ID + ".RECORD";
static final String ACTION_SHUTDOWN = BuildConfig.APPLICATION_ID + ".SHUTDOWN";
static final int VIRT_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
private MediaProjection projection;
private VirtualDisplay vdisplay;
final private HandlerThread handlerThread = new HandlerThread(getClass().getSimpleName(), android.os.Process.THREAD_PRIORITY_BACKGROUND);
private Handler handler;
private WindowManager windowManager;
private MediaProjectionManager mediaProjectionManager;
private int resultCode;
private Intent resultData;
final private ToneGenerator beeper = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
#Override
public void onCreate() {
super.onCreate();
mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
handlerThread.start();
handler=new Handler(handlerThread.getLooper());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction() == null) {
resultCode = intent.getIntExtra(EXTRA_RESULT_CODE, 1337);
resultData = intent.getParcelableExtra(EXTRA_RESULT_INTENT);
foregroundify();
}
else if (intent.getAction().equals(ACTION_RECORD)) {
if (resultData!=null) {
startCapture();
}
else {
Intent ui=
new Intent(this, Main.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(ui);
}
}
else if (intent.getAction().equals(ACTION_SHUTDOWN)) {
beeper.startTone(ToneGenerator.TONE_PROP_NACK);
stopForeground(true);
stopSelf();
}
return(START_NOT_STICKY);
}
#Override
public void onDestroy() {
stopCapture();
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
throw new IllegalStateException("Binding not supported. Go away.");
}
WindowManager getWindowManager() {
return(windowManager);
}
Handler getHandler() {
return(handler);
}
void processImage(final byte[] png) {
new Thread() {
#Override
public void run() {File output=new File(getExternalFilesDir(null),
"screenshot.png");
try {
FileOutputStream fos=new FileOutputStream(output);
fos.write(png);
fos.flush();
fos.getFD().sync();
fos.close();
MediaScannerConnection.scanFile(ScreenShotService.this,
new String[] {output.getAbsolutePath()},
new String[] {"image/png"},
null);
}
catch (Exception e) {
Log.e(getClass().getSimpleName(), "Exception writing out screenshot", e);
}
}
}.start();
beeper.startTone(ToneGenerator.TONE_PROP_ACK);
stopCapture();
}
private void stopCapture() {
if (projection!=null) {
projection.stop();
vdisplay.release();
projection=null;
}
}
private void startCapture() {
projection = mediaProjectionManager.getMediaProjection(resultCode, resultData);
ImageTransmogrifier it = new ImageTransmogrifier(this);
MediaProjection.Callback cb = new MediaProjection.Callback() {
#Override
public void onStop() {
vdisplay.release();
}
};
vdisplay=projection.createVirtualDisplay("shooter",
it.getWidth(), it.getHeight(),
getResources().getDisplayMetrics().densityDpi,
VIRT_DISPLAY_FLAGS, it.getSurface(), null, handler);
projection.registerCallback(cb, handler);
}
private void foregroundify() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL);
builder.setContentTitle(getString(R.string.app_name))
.setSmallIcon(R.drawable.rec_icon)
.setTicker(getString(R.string.app_name));
builder.addAction(R.drawable.ic_record_white_24dp,
getString(R.string.notify_record),
buildPendingIntent(ACTION_RECORD));
builder.addAction(R.drawable.ic_eject_white_24dp,
getString(R.string.notify_shutdown),
buildPendingIntent(ACTION_SHUTDOWN));
startForeground(NOTIFY_ID, builder.build());
}
private PendingIntent buildPendingIntent(String action) {
Intent i=new Intent(this, getClass());
i.setAction(action);
return(PendingIntent.getService(this, 0, i, 0));
}
}
and also imagetransmofrifier class:
public class ImageTransmogrifier implements ImageReader.OnImageAvailableListener {
private final int width;
private final int height;
private final ImageReader imageReader;
private final ScreenShotService svc;
private Bitmap latestBitmap=null;
ImageTransmogrifier(ScreenShotService svc) {
this.svc=svc;
Display display=svc.getWindowManager().getDefaultDisplay();
Point size=new Point();
display.getSize(size);
int width=size.x;
int height=size.y;
while (width*height > (2<<19)) {
width=width>>1;
height=height>>1;
}
this.width=width;
this.height=height;
imageReader=ImageReader.newInstance(width, height,
PixelFormat.RGBA_8888, 2);
imageReader.setOnImageAvailableListener(this, svc.getHandler());
}
#Override
public void onImageAvailable(ImageReader reader) {
final Image image=imageReader.acquireLatestImage();
if (image!=null) {
Image.Plane[] planes=image.getPlanes();
ByteBuffer buffer=planes[0].getBuffer();
int pixelStride=planes[0].getPixelStride();
int rowStride=planes[0].getRowStride();
int rowPadding=rowStride - pixelStride * width;
int bitmapWidth=width + rowPadding / pixelStride;
if (latestBitmap == null ||
latestBitmap.getWidth() != bitmapWidth ||
latestBitmap.getHeight() != height) {
if (latestBitmap != null) {
latestBitmap.recycle();
}
latestBitmap=Bitmap.createBitmap(bitmapWidth,
height, Bitmap.Config.ARGB_8888);
}
latestBitmap.copyPixelsFromBuffer(buffer);
if (image != null) {
image.close();
}
ByteArrayOutputStream baos=new ByteArrayOutputStream();
Bitmap cropped=Bitmap.createBitmap(latestBitmap, 0, 0,
width, height);
cropped.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] newPng=baos.toByteArray();
svc.processImage(newPng);
}
}
Surface getSurface() {
return(imageReader.getSurface());
}
int getWidth() {
return(width);
}
int getHeight() {
return(height);
}
void close() {
imageReader.close();
}
}
It only works when your hit the record button.[![button][1]][1]. Then you'll be able to find in the directory that author suggested

MediaRecorder: stop called in an invalid state: 1

I am new in android. i create one Screen Recorder App. All things is done but problem is when i stop the screen recorder then it will not stop and this error occur.when is search on google about this error then i getting that MediaRecorder is not started but when i check on my sd card then captured video is saved.I follow this tutorial here.when i start the video recording then one notification is popup after click on then notification stop message then using service i try to stop mediaRecorder to stop but its not stopping and and error occur.If any one can help me then thanks in advance.
Problem
MediaRecorder.stop() not workging.
MainActivity.java
public class MainActivity extends Activity {
private static final int REQUEST_CODE = 1000;
private static final String TAG = "MainActivity";
private ScreenRecorder mScreenRecorder;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mScreenRecorder = RecorderApplication.getApplication(this).getRecorder();
shareScreen();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != REQUEST_CODE) {
Log.e(TAG, "Unknown request code: " + requestCode);
return;
}
if (resultCode != RESULT_OK) {
Toast.makeText(this, "Screen Cast Permission Denied", Toast.LENGTH_SHORT).show();
return;
}
mScreenRecorder.initRecorder();
mScreenRecorder.initShareScreen(resultCode, data);
finish();
}
private void shareScreen() {
if (mScreenRecorder.getMediaProjection() == null) {
Log.i("getMediaProjection()..."," is null");
startActivityForResult(mScreenRecorder.getMediaProjectionManager().createScreenCaptureIntent(), REQUEST_CODE);
return;
}
mScreenRecorder.initRecorder();
mScreenRecorder.shareScreen();
finish();
}
}
ScreenRecorder.java
public class ScreenRecorder {
private Context mContext;
private WindowManager mWindowManager;
private int mScreenDensity;
private MediaProjectionManager mProjectionManager;
private MediaProjection mMediaProjection;
private VirtualDisplay mVirtualDisplay;
private Surface surface;
private MediaProjectionCallback mMediaProjectionCallback;
public MediaRecorder mMediaRecorder;
private String mTargetRecordFileName;
private String mTargetRecordFilePath;
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
public static final String NOTIFICATION_EXTRA = "Extra";
public static final int EXTRA_PLAY = 0;
public static final int EXTRA_PAUSE = 1;
public static final int EXTRA_STOP = 2;
public int flag = 0;
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);
}
public ScreenRecorder(Context context, WindowManager windowManager) {
mContext = context;
mWindowManager = windowManager;
DisplayMetrics metrics = new DisplayMetrics();
mWindowManager.getDefaultDisplay().getMetrics(metrics);
mScreenDensity = metrics.densityDpi;
mMediaRecorder = new MediaRecorder();
mProjectionManager = (MediaProjectionManager) mContext.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
}
public MediaProjection getMediaProjection() {
return mMediaProjection;
}
public MediaProjectionManager getMediaProjectionManager() {
return mProjectionManager;
}
public void initShareScreen(int resultCode, Intent data) {
mMediaProjectionCallback = new MediaProjectionCallback();
mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
mMediaProjection.registerCallback(mMediaProjectionCallback, null);
shareScreen();
}
public void shareScreen() {
mVirtualDisplay = createVirtualDisplay();
mMediaRecorder.start();
flag = 1;
Log.i("shareScreen()...","mMediaRecorder.start()");
Log.i("shareScreen()...",".."+flag);
// showRunningNotification();
showControlNotification();
}
private VirtualDisplay createVirtualDisplay() {
int screen_width = mContext.getResources().getDisplayMetrics().widthPixels;
int screen_height = mContext.getResources().getDisplayMetrics().heightPixels;
surface = mMediaRecorder.getSurface();
return mMediaProjection.createVirtualDisplay("MainActivity",
screen_width, screen_height, mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mMediaRecorder.getSurface(), null, null);
}
public void initRecorder() {
SharedPreferences mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
int screen_width = mContext.getResources().getDisplayMetrics().widthPixels;
int screen_height = mContext.getResources().getDisplayMetrics().heightPixels;
Log.i("initRecorder()...", " Initialization is Completed");
try {
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setVideoSize(screen_width, screen_height);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setOutputFile(getSaveVideoFolder());
mMediaRecorder.setVideoEncodingBitRate(512 * 1000);
mMediaRecorder.prepare();
System.out.println("..........Media Recorder is Ready for Recording......");
} catch (IOException e) {
e.printStackTrace();
}
}
private String getSaveVideoFolder() {
File folder = new File(Environment.getExternalStorageDirectory()
+ "/ScreenRecorder");
if (!folder.exists()) {
folder.mkdirs();
}
mTargetRecordFileName = Utils.convertDateToString(new Date()) + ".mp4";
mTargetRecordFilePath = folder.getAbsolutePath() + "/"
+ mTargetRecordFileName;
return mTargetRecordFilePath;
}
private class MediaProjectionCallback extends MediaProjection.Callback {
#Override
public void onStop() {
mMediaRecorder.stop();
mMediaRecorder.reset();
Log.v("ScreenRecorder...", "Recording Stopped");
mMediaProjection = null;
stopScreenSharing();
}
}
private void stopScreenSharing() {
if (mVirtualDisplay == null) {
return;
}
mVirtualDisplay.release();
// mMediaRecorder.release(); //If used: mMediaRecorder object cannot
// be reused again
destroyMediaProjection();
}
private void destroyMediaProjection() {
Log.i("destroyMediaProjection()...","called");
if (mMediaProjection != null) {
mMediaProjection.unregisterCallback(mMediaProjectionCallback);
mMediaProjection.stop();
// mMediaProjection = null;
Log.i("destroyMediaProjection()...","not null");
}
}
private static int NOTIFICATION_RUNNING = 109;
private static int NOTIFICATION_CONTROL = 110;
private static int NOTIFICATION_DONE = 111;
private void showControlNotification() {
Intent intentPause = new Intent(mContext, FloatingViewService.class);
intentPause.setAction("PAUSE");
PendingIntent pIntentPause = PendingIntent.getService(mContext, 0,
intentPause, 0);
Intent intentStop = new Intent(mContext, FloatingViewService.class);
intentStop.setAction("STOP");
PendingIntent pIntentStop = PendingIntent.getService(mContext, 0, intentStop, 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
mContext);
mBuilder.setSmallIcon(R.drawable.ic_notification);
mBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
mBuilder.setContentTitle("Recording controls");
mBuilder.setPriority(Notification.PRIORITY_MAX);
mBuilder.setOngoing(true);
mBuilder.setWhen(0);
// if (!isPauseRecorder) {
// mBuilder.addAction(R.drawable.ic_action_pause, "PAUSE",
// pIntentPause);
// } else {
// mBuilder.addAction(R.drawable.ic_action_video, "RESUME",
// pIntentPause);
// }
mBuilder.addAction(R.drawable.ic_action_stop, "STOP", pIntentStop);
Notification notification = mBuilder.build();
notification.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
NotificationManager mNotificationManager = (NotificationManager) mContext
.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(NOTIFICATION_CONTROL, notification);
}
public void stopRecorder() {
try {
if (mMediaRecorder != null){
Log.i("flag...","..."+flag);
mMediaRecorder.stop();
mMediaRecorder.reset();
// mMediaProjection.stop();
stopScreenSharing();
}else{
Log.i("mMediaRecorder...in stopRecorder()"," is null");
}
}catch (Exception e){
Log.e("Error to stop media recorder in stopRecorder() method... :- "," "+e.getMessage());
e.printStackTrace();
}
NotificationManager mNotificationManager = (NotificationManager) mContext
.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(NOTIFICATION_CONTROL);
mNotificationManager.cancel(NOTIFICATION_RUNNING);
// showDoneNotification();
// TODO save info to database
DatabaseHelper mDatabaseHelper = new DatabaseHelper(mContext);
mDatabaseHelper.addVideo(mTargetRecordFilePath);
// appendToFile(mTargetRecordFileName, getTemporaryFileName());
}
private String getTemporaryFileName() {
return mContext.getExternalCacheDir().getAbsolutePath()
+ File.separator + "tmprecord.mp4";
}
private void appendToFile(#NonNull final String targetFileName,
#NonNull final String newFileName) {
Mp4ParserWrapper.append(targetFileName, newFileName);
}
}
FloatingViewService.java
public class FloatingViewService extends Service {
private WindowManager windowManager;
private View floatingView;
private TextView mTextCoolDown;
private WindowManager.LayoutParams params;
private WindowManager.LayoutParams paramsCoolDown;
private ImageView btnCamera;
private ImageView btnSettings;
private ImageView btnAlbum;
private ImageView btnExit;
public static final String NOTIFICATION = "com.example.screenrecorder";
private ScreenRecorder mScreenRecorder ;
private ScreenRecorder mScreenRecorder1 ;
private int cooldown = 3;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
windowManager = (WindowManager)this.getSystemService(Context.WINDOW_SERVICE);
mScreenRecorder = new ScreenRecorder(getApplicationContext(), windowManager);
if (intent != null) {
if (intent.getAction() != null) {
Log.i("intent Action...",intent.getAction());
if (intent.getAction().equals("PAUSE")) {
} else if (intent.getAction().equals("STOP")) {
mScreenRecorder.stopRecorder();
try{
showFloatingView();
}catch (RuntimeException e){
}
}
}
}
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
initView();
}
#Override
public void onDestroy() {
super.onDestroy();
if (floatingView != null)
windowManager.removeView(floatingView);
}
private void initView() {
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
int screen_height = getResources().getDisplayMetrics().heightPixels;
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
floatingView = inflater.inflate(R.layout.floating_view, null);
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 100;
btnCamera = (ImageView) floatingView.findViewById(R.id.btn_camera);
btnSettings = (ImageView) floatingView.findViewById(R.id.btn_settings);
btnAlbum = (ImageView) floatingView.findViewById(R.id.btn_album);
btnExit = (ImageView) floatingView.findViewById(R.id.btn_close);
btnCamera.setOnTouchListener(new OnItemTouchListener(0));
btnSettings.setOnTouchListener(new OnItemTouchListener(1));
btnAlbum.setOnTouchListener(new OnItemTouchListener(2));
btnExit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
stopSelf();
}
});
setFloatingViewMove();
}
private void showFloatingView() {
windowManager.addView(floatingView, params);
}
private void hideFloatingView() {
windowManager.removeView(floatingView);
}
private int mAction = -1;
long onTouchTime = -1;
long TIME_CLICK = 200;
private class OnItemTouchListener implements OnTouchListener {
private int action;
public OnItemTouchListener(int action) {
this.action = action;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mAction = action;
v.setBackgroundResource(R.drawable.bg_item_selected);
onTouchTime = System.currentTimeMillis();
break;
}
return false;
}
}
private void setFloatingViewMove() {
floatingView.setOnTouchListener(new OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
break;
case MotionEvent.ACTION_UP:
Log.d("phucdl", "start recorder " + (System.currentTimeMillis() - onTouchTime));
if (System.currentTimeMillis() - onTouchTime < TIME_CLICK) {
Intent intent;
switch (mAction) {
case 0:
if (RecorderApplication.getApplication(FloatingViewService.this).getRecorder() == null) {
mScreenRecorder = new ScreenRecorder(FloatingViewService.this, windowManager);
RecorderApplication.getApplication(FloatingViewService.this).setRecorder(mScreenRecorder);
}
intent = new Intent(FloatingViewService.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
hideFloatingView();
break;
case 1:
intent = new Intent(FloatingViewService.this, PreferencesActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
hideFloatingView();
break;
case 2:
intent = new Intent(FloatingViewService.this, AlbumActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
hideFloatingView();
break;
default:
break;
}
}
btnCamera.setBackgroundDrawable(null);
btnSettings.setBackgroundDrawable(null);
btnAlbum.setBackgroundDrawable(null);
btnExit.setBackgroundDrawable(null);
break;
case MotionEvent.ACTION_MOVE:
params.x = initialX
+ (int) (event.getRawX() - initialTouchX);
params.y = initialY
+ (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(floatingView, params);
break;
}
return false;
}
});
}
}
Log is
08-17 20:43:07.537 13733-13733/com.example.screenrecorder E/MediaRecorder: stop called in an invalid state: 1
08-17 20:43:07.537 13733-13733/com.example.screenrecorder E/Error to stop media recorder in stopRecorder() method... :-: null
08-17 20:43:07.537 13733-13733/com.example.screenrecorder W/System.err: java.lang.IllegalStateException
08-17 20:43:07.537 13733-13733/com.example.screenrecorder W/System.err: at android.media.MediaRecorder.stop(Native Method)
08-17 20:43:07.537 13733-13733/com.example.screenrecorder W/System.err: at com.gameapp.screenrecorder.ScreenRecorder.stopRecorder(ScreenRecorder.java:371)
08-17 20:43:07.537 13733-13733/com.example.screenrecorder W/System.err: at com.gameapp.screenrecorder.FloatingViewService.onStartCommand(FloatingViewService.java:59)
08-17 20:43:07.537 13733-13733/com.example.screenrecorder W/System.err: at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3010)
08-17 20:43:07.537 13733-13733/com.example.screenrecorder W/System.err: at android.app.ActivityThread.-wrap17(ActivityThread.java)
08-17 20:43:07.537 13733-13733/com.example.screenrecorder W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1442)
08-17 20:43:07.538 13733-13733/com.example.screenrecorder W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
08-17 20:43:07.538 13733-13733/com.example.screenrecorder W/System.err: at android.os.Looper.loop(Looper.java:148)
08-17 20:43:07.538 13733-13733/com.example.screenrecorder W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5417)
08-17 20:43:07.538 13733-13733/com.example.screenrecorder W/System.err: at java.lang.reflect.Method.invoke(Native Method)
08-17 20:43:07.538 13733-13733/com.example.screenrecorder W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
08-17 20:43:07.538 13733-13733/com.example.screenrecorder W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
08-17 20:43:07.732 13733-13750/com.example.screenrecorder W/EGL_emulation: eglSurfaceAttrib not implemented
08-17 20:43:07.732 13733-13750/com.example.screenrecorder W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xed6bf5a0, error=EGL_SUCCESS
08-17 20:43:09.433 13733-13750/com.example.screenrecorder E/Surface: getSlotFromBufferLocked: unknown buffer: 0xee9722a0
you create an Object of ScreenRecorder class First time in FloatingViewService class inside setFloatingViewMove() method that's ok but when you click on Stop then you again create ScreenRecorder class object then it's constructor is called and your previous MediaRacoder object is newly Initialized and then after you call stop method but mediarecoder start method is not called newly initialized mediarecorder instance that's why this exception is occurred. Just commant or remove one line in you FloatingViewService class in onStartCommand() method.I hope this will solve your problem.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
windowManager = (WindowManager)this.getSystemService(Context.WINDOW_SERVICE);
// mScreenRecorder = new ScreenRecorder(getApplicationContext(), windowManager);
}

OnCameraFrame method of CvCameraViewListener interface not being called

I am new to opencv and trying to create a simple application which will open the camera and capture the photo. I have implemented the CvCameraViewListener interface for this purpose. My code looks as follows:
MainActivity.java
public class MainActivity extends Activity implements CvCameraViewListener2{
public String TAG = "MainActivity";
private int mCameraIndex;
private Mat mBgr;
private Boolean mIsPhotoPending;
private CameraBridgeViewBase mCameraView;
private static final String STATE_CAMERA_INDEX = "cameraIndex";
private Boolean mIsMenuLocked;
private CameraBridgeViewBase.CvCameraViewFrame inputFrame;
int screen_w, screen_h;
private Mat gray, frame, lowRes;
static {
if (!OpenCVLoader.initDebug()) {
Log.v("MainActivity","Loading of OpenCv Failed");
}
}
private BaseLoaderCallback mLoaderCallBack = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch(status) {
case LoaderCallbackInterface.SUCCESS:
{
String TAG = "";
Log.i(TAG, "Open CV successfully loaded");
mCameraView.enableView();
mBgr = new Mat();
}break;
default:
{
super.onManagerConnected(status);
}break;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if(savedInstanceState != null)
{
mCameraIndex = savedInstanceState.getInt(STATE_CAMERA_INDEX, 0);
}
else
{
mCameraIndex = 0;
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD)
{
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(mCameraIndex, cameraInfo);
}
mCameraView = new NativeCameraView(this, mCameraIndex);
//mCameraView.setCvCameraViewListener(this);
findViewById(R.id.HelloOpenCvView);
//mOpenCvCameraView = new JavaCameraView(this,-1);
setContentView(mCameraView);
}
#Override
public void onResume() {
super.onResume();
mLoaderCallBack.onManagerConnected(LoaderCallbackInterface.SUCCESS);
// OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_11, this, mLoaderCallBack);
mIsMenuLocked = false;
}
#Override
public void onPause() {
super.onPause();
if(mCameraView != null)
mCameraView.disableView();
}
public void onDestroy() {
super.onDestroy();
if(mCameraView != null)
mCameraView.disableView();
}
#Override
public void onCameraViewStarted(int width, int height) {
}
#Override
public void onCameraViewStopped() {
}
#Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
Mat rgba = inputFrame.rgba();
if(mIsPhotoPending)
{
takePhoto(rgba);
}
return rgba;
}
private void takePhoto(Mat rgba)
{
//get the path of the photo
final long currentTimeMillis = System.currentTimeMillis();
final String appName = getString(R.string.app_name);
final String galleryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
final String albumPath = galleryPath + "/" + appName;
final String photoPath = albumPath + "/" + currentTimeMillis + ".png";
final ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, photoPath);
values.put(MediaStore.Images.Media.MIME_TYPE, showActivity.PHOTO_MIME_TYPE);
values.put(MediaStore.Images.Media.TITLE, appName);
values.put(MediaStore.Images.Media.DESCRIPTION, appName);
values.put(MediaStore.Images.Media.DATE_TAKEN, currentTimeMillis);
//check if the album directory exists
File album = new File(albumPath);
if(!album.isDirectory() && !album.mkdirs())
{
Log.e(TAG,"Failed to create album directory at" + albumPath);
return;
}
//try to create the photo
Imgproc.cvtColor(rgba, mBgr, Imgproc.COLOR_RGBA2BGR, 3);
if(!Highgui.imwrite(photoPath, mBgr))
{
Log.d(TAG,"Photo saved successfully");
onTakePhotoFailed();
}
Log.d(TAG, "Photo saved successfully");
//insert photo in mediastore
Uri uri;
final Intent intent = new Intent();
try
{
uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
intent.putExtra(showActivity.EXTRA_PHOTO_URI, uri);
}catch(final Exception e)
{
Log.e(TAG, "Failed to insert photo into media store");
e.printStackTrace();
}
//delete the photo because insertion failed
File photo = new File(photoPath);
if(!photo.delete())
{
Log.e(TAG, "Failed to delete non-inserted photo");
}
onTakePhotoFailed();
intent.putExtra(showActivity.EXTRA_PHOTO_DATA_PATH, photoPath);
startActivity(intent);
return;
}
private void onTakePhotoFailed()
{
mIsMenuLocked = false;
//display error message
final String errorMessage = getString(R.string.photo_error_message);
runOnUiThread(new Runnable()
{
#Override
public void run()
{
Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
}
});
}
My problem is that the onCameraFrame() method is never being called which in turn does not call the takePhoto() method and I am not able to capture the photo. I have called the takePhoto() method within the onCamerFrame() method as the method will take the Mat details. Kindly let me know where did I go wrong.
Any help would be highly appreciated.
You've commented out the camera listener. That's why onCameraFrame() is never called. Uncomment this in onCreate():
mCameraView.setCvCameraViewListener(this);
You may need to implement the PictureCallBack interface your activity. Refer the Tutorial 3 - Camera Control App.

Getting orientation for an activity

I need to get the orientation of a device. The screen orientation of the device is fixed as portrait.I have used the following code but it doesn't seem to work.I have made changes in the manifest file
due to which
getResources().getConfiguration().orientation;
always gives the same value
public final class CaptureActivity extends Activity implements SurfaceHolder.Callback,SensorEventListener{
private static final String TAG = CaptureActivity.class.getSimpleName();
private static final long DEFAULT_INTENT_RESULT_DURATION_MS = 1500L;
private static final long BULK_MODE_SCAN_DELAY_MS = 1000L;
private static final String PACKAGE_NAME = "com.google.zxing.client.android";
private static final String PRODUCT_SEARCH_URL_PREFIX = "http://www.google";
private static final String PRODUCT_SEARCH_URL_SUFFIX = "/m/products/scan";
private static final String[] ZXING_URLS = { "http://zxing.appspot.com/scan", "zxing://scan/" };
public static final int HISTORY_REQUEST_CODE = 0x0000bacc;
private static final Set<ResultMetadataType> DISPLAYABLE_METADATA_TYPES =
EnumSet.of(ResultMetadataType.ISSUE_NUMBER,
ResultMetadataType.SUGGESTED_PRICE,
ResultMetadataType.ERROR_CORRECTION_LEVEL,
ResultMetadataType.POSSIBLE_COUNTRY);
private CameraManager cameraManager;
private CaptureActivityHandler handler;
private Result savedResultToShow;
private ViewfinderView viewfinderView;
//private TextView statusView;
//private View resultView;
private Result lastResult;
private boolean hasSurface;
private boolean copyToClipboard;
private IntentSource source;
private String sourceUrl;
private ScanFromWebPageManager scanFromWebPageManager;
private Collection<BarcodeFormat> decodeFormats;
private Map<DecodeHintType,?> decodeHints;
private String characterSet;
private HistoryManager historyManager;
private InactivityTimer inactivityTimer;
private BeepManager beepManager;
private AmbientLightManager ambientLightManager;
private int orientation;
private SensorManager mSensorManager;
private Sensor mAccelerometer;
ViewfinderView getViewfinderView() {
return viewfinderView;
}
public Handler getHandler() {
return handler;
}
CameraManager getCameraManager() {
return cameraManager;
}
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.capture);
hasSurface = false;
historyManager = new HistoryManager(this);
historyManager.trimHistory();
inactivityTimer = new InactivityTimer(this);
beepManager = new BeepManager(this);
ambientLightManager = new AmbientLightManager(this);
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
//showHelpOnFirstLaunch();
}
#Override
protected void onResume() {
super.onResume();
// CameraManager must be initialized here, not in onCreate(). This is necessary because we don't
// want to open the camera driver and measure the screen size if we're going to show the help on
// first launch. That led to bugs where the scanning rectangle was the wrong size and partially
// off screen.
cameraManager = new CameraManager(getApplication());
viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
viewfinderView.setCameraManager(cameraManager);
WindowManager manager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
int orientaionWidth = display.getWidth();
int orientaionHeight = display.getHeight();
int rotation=display.getRotation();
int orien=getResources().getConfiguration().orientation;
boolean orientation = false;
if(orientaionWidth>orientaionHeight){
orientation=true;
}
if(orien==1){
setLandscape(true);
}else{
setLandscape(false);
}
handler = null;
lastResult = null;
resetStatusView();
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) {
// The activity was paused but not stopped, so the surface still exists. Therefore
// surfaceCreated() won't be called, so init the camera here.
initCamera(surfaceHolder);
} else {
// Install the callback and wait for surfaceCreated() to init the camera.
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
beepManager.updatePrefs();
ambientLightManager.start(cameraManager);
inactivityTimer.onResume();
Intent intent = getIntent();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
copyToClipboard = prefs.getBoolean(PreferencesActivity.KEY_COPY_TO_CLIPBOARD, true)
&& (intent == null || intent.getBooleanExtra(Intents.Scan.SAVE_HISTORY, true));
source = IntentSource.NONE;
decodeFormats = null;
characterSet = null;
if (intent != null) {
String action = intent.getAction();
String dataString = intent.getDataString();
if (Intents.Scan.ACTION.equals(action)) {
// Scan the formats the intent requested, and return the result to the calling activity.
source = IntentSource.NATIVE_APP_INTENT;
decodeFormats = DecodeFormatManager.parseDecodeFormats(intent);
decodeHints = DecodeHintManager.parseDecodeHints(intent);
if (intent.hasExtra(Intents.Scan.WIDTH) && intent.hasExtra(Intents.Scan.HEIGHT)) {
int width = intent.getIntExtra(Intents.Scan.WIDTH, 0);
int height = intent.getIntExtra(Intents.Scan.HEIGHT, 0);
if (width > 0 && height > 0) {
cameraManager.setManualFramingRect(width, height);
}
}
String customPromptMessage = intent.getStringExtra(Intents.Scan.PROMPT_MESSAGE);
} else if (dataString != null &&
dataString.contains(PRODUCT_SEARCH_URL_PREFIX) &&
dataString.contains(PRODUCT_SEARCH_URL_SUFFIX)) {
// Scan only products and send the result to mobile Product Search.
source = IntentSource.PRODUCT_SEARCH_LINK;
sourceUrl = dataString;
decodeFormats = DecodeFormatManager.PRODUCT_FORMATS;
} else if (isZXingURL(dataString)) {
// Scan formats requested in query string (all formats if none specified).
// If a return URL is specified, send the results there. Otherwise, handle it ourselves.
source = IntentSource.ZXING_LINK;
sourceUrl = dataString;
Uri inputUri = Uri.parse(dataString);
scanFromWebPageManager = new ScanFromWebPageManager(inputUri);
decodeFormats = DecodeFormatManager.parseDecodeFormats(inputUri);
// Allow a sub-set of the hints to be specified by the caller.
decodeHints = DecodeHintManager.parseDecodeHints(inputUri);
}
characterSet = intent.getStringExtra(Intents.Scan.CHARACTER_SET);
}
}
#Override
protected void onPause() {
if (handler != null) {
handler.quitSynchronously();
handler = null;
}
inactivityTimer.onPause();
ambientLightManager.stop();
cameraManager.closeDriver();
if (!hasSurface) {
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
surfaceHolder.removeCallback(this);
}
super.onPause();
}
#Override
protected void onDestroy() {
inactivityTimer.shutdown();
super.onDestroy();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode == RESULT_OK) {
if (requestCode == HISTORY_REQUEST_CODE) {
int itemNumber = intent.getIntExtra(Intents.History.ITEM_NUMBER, -1);
if (itemNumber >= 0) {
HistoryItem historyItem = historyManager.buildHistoryItem(itemNumber);
decodeOrStoreSavedBitmap(null, historyItem.getResult());
}
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (holder == null) {
Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
}
if (!hasSurface) {
hasSurface = true;
initCamera(holder);
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
hasSurface = false;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
private static void drawLine(Canvas canvas, Paint paint, ResultPoint a, ResultPoint b, float scaleFactor) {
if (a != null && b != null) {
canvas.drawLine(scaleFactor * a.getX(),
scaleFactor * a.getY(),
scaleFactor * b.getX(),
scaleFactor * b.getY(),
paint);
}
}
private void sendReplyMessage(int id, Object arg, long delayMS) {
Message message = Message.obtain(handler, id, arg);
if (delayMS > 0L) {
handler.sendMessageDelayed(message, delayMS);
} else {
handler.sendMessage(message);
}
}
/**
* We want the help screen to be shown automatically the first time a new version of the app is
* run. The easiest way to do this is to check android:versionCode from the manifest, and compare
* it to a value stored as a preference.
*/
private boolean showHelpOnFirstLaunch() {
/* try {
PackageInfo info = getPackageManager().getPackageInfo(PACKAGE_NAME, 0);
int currentVersion = info.versionCode;
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
int lastVersion = prefs.getInt(PreferencesActivity.KEY_HELP_VERSION_SHOWN, 0);
if (currentVersion > lastVersion) {
prefs.edit().putInt(PreferencesActivity.KEY_HELP_VERSION_SHOWN, currentVersion).commit();
Intent intent = new Intent(this, HelpActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
// Show the default page on a clean install, and the what's new page on an upgrade.
String page = lastVersion == 0 ? HelpActivity.DEFAULT_PAGE : HelpActivity.WHATS_NEW_PAGE;
intent.putExtra(HelpActivity.REQUESTED_PAGE_KEY, page);
startActivity(intent);
return true;
}
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, e);
}*/
return false;
}
private void initCamera(SurfaceHolder surfaceHolder) {
if (surfaceHolder == null) {
throw new IllegalStateException("No SurfaceHolder provided");
}
if (cameraManager.isOpen()) {
Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
return;
}
try {
cameraManager.openDriver(surfaceHolder);
// Creating the handler starts the preview, which can also throw a RuntimeException.
if (handler == null) {
handler = new CaptureActivityHandler(this, decodeFormats, decodeHints, characterSet, cameraManager);
}
decodeOrStoreSavedBitmap(null, null);
} catch (IOException ioe) {
Log.w(TAG, ioe);
displayFrameworkBugMessageAndExit();
} catch (RuntimeException e) {
// Barcode Scanner has seen crashes in the wild of this variety:
// java.?lang.?RuntimeException: Fail to connect to camera service
Log.w(TAG, "Unexpected error initializing camera", e);
displayFrameworkBugMessageAndExit();
}
}
private void displayFrameworkBugMessageAndExit() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.app_name));
builder.setMessage(getString(R.string.msg_camera_framework_bug));
builder.setPositiveButton(R.string.button_ok, new FinishListener(this));
builder.setOnCancelListener(new FinishListener(this));
builder.show();
}
public void restartPreviewAfterDelay(long delayMS) {
if (handler != null) {
handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
}
resetStatusView();
}
private void resetStatusView() {
viewfinderView.setVisibility(View.VISIBLE);
lastResult = null;
}
public void drawViewfinder() {
viewfinderView.drawViewfinder();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
public void setLandscape(boolean orientation) {
viewfinderView.setLandscape(orientation);
}
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent arg0) {
if (arg0.values[1]<6.5 && arg0.values[1]>-6.5) {
if (orientation!=1) {
Log.d("Sensor", "Landscape");
}
orientation=1;
} else {
if (orientation!=0) {
Log.d("Sensor", "Portrait");
}
orientation=0;
}
}
}
You can get the current orientation through
Activity.getResources().getConfiguration().orientation
or
getActivity().getResources().getConfiguration().orientation
this should work...
int orientation = getResources().getConfiguration().orientation;
if(orientation == Configuration.ORIENTATION_PORTRAIT) {
Log.i(TAG, "Portrait");
} else if(orientation == Configuration.ORIENTATION_LANDSCAPE) {
Log.i(TAG, "LandScape");
}
It should be
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
/* Now we can retrieve all display-related infos */
int width = display.getWidth();
int height = display.getHeight();
int rotation = display.getRotation();
Also, try with Activity().getResources().getConfiguration().orientation
By setting the orientation to be fixed to portrait in the manifest, you cant use getResources().getConfiguration().orientation as you already know.
Try using the accelerometer to determine the current rotation/tilt of the device as described here, How do I use the Android Accelerometer?

Categories

Resources