The title is a little vague, but the problem is a little tricky to explain, so here goes...
(In this context, as I do not fully have the vernacular down, I use the term "Child Activity" to mean an activity that was launched via an intent from a parent activity, within the same app.)
I build a simple, sample app to bring up the camera, and read a barcode. It works fine, until it is launched from another activity that I put in front of it. Then the autofocus does not work.
The SDK, google play libraries, versions do not have a bearing on the problem, since it does work in one activity, but not when launched by another.
Lastly, I did not deal with posting for "ActivityResult" in this example. This is not related to the issue I am experiencing.
I created a MainActivity. I did not include superflous classes like camera preview, layouts, icons, etc, as they are not needed to identify this problem. If necessary, and can make the a zip file available to anyone to download it. This is to only demonstrate the two activities.
package com.digitalcheck.barcodedecode;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.widget.FrameLayout;
import android.widget.TextView;
import org.json.JSONObject;
public class MainActivity extends AppCompatActivity {
public static final String EXTRA_REPLY = "extra.REPLY";
private final Handler m_handler = new Handler();
private TextView m_status;
private boolean m_cameraPresent;
private CameraPreview m_preview;
private Camera m_camera;
private FrameLayout m_cameraFrame;
private Decode m_decode;
private String m_data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
m_status = (TextView) findViewById(R.id.textView);
m_cameraFrame = (FrameLayout) findViewById(R.id.camerapreview) ;
m_camera = null;
m_preview = null;
m_decode = null;
m_cameraPresent = getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
if (m_cameraPresent == false) {
m_status.setText("No Camera was found on this device");
}
ActivateCamera();
}
final Runnable UpdateScreen = new Runnable() {
public void run() {
int x;
String user;
String key, value;
JSONObject jitem;
m_cameraFrame.removeAllViews();
m_status.setText(m_data);
}
};
public void BarcodeData(String data) {
m_data = data;
m_handler.post(UpdateScreen);
}
final Runnable Refocus = new Runnable() {
public void run() {
m_camera.autoFocus(m_decode);
}
};
public void TryAgain() {
m_handler.post(Refocus);
}
/*************************************
* Overrides
**************************************/
@Override
public void onPostResume() {
super.onPostResume();
if (m_camera == null) {
ActivateCamera();
}
if (m_camera != null) {
m_camera.autoFocus(m_decode);
}
}
@Override
public void onPause() {
super.onPause();
if (m_camera != null) {
m_camera.release();
m_camera = null;
m_preview = null;
m_decode = null;
}
}
/*****************************************************
* Internal Functions
***************************************/
private void ActivateCamera() {
if (m_camera != null) {
m_camera = null;
}
try {
m_camera = Camera.open();
} catch (Exception e) {
m_status.setText("The camera could not be accessed");
}
if (m_decode != null) {
m_decode = null;
}
m_decode = new Decode(this);
if (m_preview != null) {
m_preview = null;
}
try {
Camera.Parameters params;
params = m_camera.getParameters();
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
params.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
m_camera.setParameters(params);
} catch (Exception e) {
}
m_preview = new CameraPreview(this, m_camera);
m_cameraFrame.addView(m_preview);
}
}
And when it launches it works fine. The camera comes up, it autofocuses in a loop until the can decode the image. Then passes it back by calling a function which spawns a "runnable".
Then I created an activity to "put in front" of this one. I called int Main2Activity (as auto generated by Android Studio), and I launch "MainActivity" it with an intent.
package com.digitalcheck.barcodedecode;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
public class Main2Activity extends AppCompatActivity {
private final int CAMERA_REQUEST = 1;
private String m_data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
}
public void OpenCamera(View view) {
Intent intent = new Intent(this,MainActivity.class);
startActivityForResult(intent,CAMERA_REQUEST);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode,resultCode,data);
if (requestCode == CAMERA_REQUEST) {
if (resultCode == RESULT_OK) {
m_data = data.getStringExtra(MainActivity.EXTRA_REPLY);
if (m_data.length() > 0) {
}
}
}
}
}
Obviously I also updated the manifest by swapping the two activities:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.digitalcheck.barcodedecode">
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:screenOrientation="landscape"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"></activity>
<activity
android:name=".Main2Activity"
android:label="Barcode Decode"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Both activities are included in my single app. All I do is change the manifest to launch "Main2Activity" instead of "MainActivity" and the autofocus stops working.
It's an easy and obvious test. When launching MainActivity, I can hold some paper in front of the camera, and watch it autofocus. When launching Main2Activity, then press the button to bring up MainActivity, it shows the camera, but the autofocus never occurs, and the autofocus callback never happens.
And yet the camera is the same class. So the issue must lie elsewhere.
Any advice would be appreciated.
-Scotty EDIT: As I cannot attach a zip file of code, but I can embed an image. A picture is worth 1000 words (or a word is one milli-picture)
I hope this helps clear up any vagaries in my description.
EDIT 2:
In the hopes of obtaining help from a more experienced Android developer than myself, I created a GitHub account, and put a zip of the example app on it.
https://github.com/scotty2541/AndroidCamera
Detailing the issue, simply changing the manifest to launch the MainActivity vs using Main2Activity shows the AutoFocus working with the former but not the latter.
-Scotty