Android Studio не удалось найти «libiconv.so»

У меня проблема с моим приложением сканирования штрих-кода, код работает отлично до тех пор, пока я не проверю кнопку «Сканирование», в этот момент он сбой, и я получаю следующую ошибку:

01-28 23:15:51.314 2261-2261/com.example.sage.appp E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.example.sage.appp, PID: 2261 java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.sage.appp-2/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libiconv.so" at java.lang.Runtime.loadLibrary(Runtime.java:366) at java.lang.System.loadLibrary(System.java:989) at com.example.sage.appp.ZBarScannerActivity.<clinit>(ZBarScannerActivity.java:28) at java.lang.reflect.Constructor.newInstance(Native Method) at java.lang.Class.newInstance(Class.java:1572) at android.app.Instrumentation.newActivity(Instrumentation.java:1065) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360) at android.app.ActivityThread.access$800(ActivityThread.java:144) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5221) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 

Это классы, которые я использую:

MainActivity.java

 package com.example.sage.appp; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.Toast; import net.sourceforge.zbar.Symbol; public class MainActivity extends Activity { private static final int ZBAR_SCANNER_REQUEST = 0; private static final int ZBAR_QR_SCANNER_REQUEST = 1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void launchScanner(View v) { if (isCameraAvailable()) { Intent intent = new Intent(this, ZBarScannerActivity.class); startActivityForResult(intent, ZBAR_SCANNER_REQUEST); } else { Toast.makeText(this, "Rear Facing Camera Unavailable", Toast.LENGTH_SHORT).show(); } } public void launchQRScanner(View v) { if (isCameraAvailable()) { Intent intent = new Intent(this, ZBarScannerActivity.class); intent.putExtra(ZBarConstants.SCAN_MODES, new int[]{Symbol.QRCODE}); startActivityForResult(intent, ZBAR_SCANNER_REQUEST); } else { Toast.makeText(this, "Rear Facing Camera Unavailable", Toast.LENGTH_SHORT).show(); } } public boolean isCameraAvailable() { PackageManager pm = getPackageManager(); return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case ZBAR_SCANNER_REQUEST: case ZBAR_QR_SCANNER_REQUEST: if (resultCode == RESULT_OK) { Toast.makeText(this, "Scan Result = " + data.getStringExtra(ZBarConstants.SCAN_RESULT), Toast.LENGTH_SHORT).show(); } else if(resultCode == RESULT_CANCELED && data != null) { String error = data.getStringExtra(ZBarConstants.ERROR_INFO); if(!TextUtils.isEmpty(error)) { Toast.makeText(this, error, Toast.LENGTH_SHORT).show(); } } break; } } 

}

ZBarScannerActivity.java

 package com.example.sage.appp; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.hardware.Camera; import android.os.Bundle; import android.os.Handler; import android.text.TextUtils; import android.view.Window; import android.view.WindowManager; import net.sourceforge.zbar.Config; import net.sourceforge.zbar.Image; import net.sourceforge.zbar.ImageScanner; import net.sourceforge.zbar.Symbol; import net.sourceforge.zbar.SymbolSet; public class ZBarScannerActivity extends Activity implements Camera.PreviewCallback, ZBarConstants { private static final String TAG = "ZBarScannerActivity"; private CameraPreview mPreview; private Camera mCamera; private ImageScanner mScanner; private Handler mAutoFocusHandler; private boolean mPreviewing = true; static { System.loadLibrary("iconv"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(!isCameraAvailable()) { // Cancel request if there is no rear-facing camera. cancelRequest(); return; } // Hide the window title. requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); mAutoFocusHandler = new Handler(); // Create and configure the ImageScanner; setupScanner(); // Create a RelativeLayout container that will hold a SurfaceView, // and set it as the content of our activity. mPreview = new CameraPreview(this, this, autoFocusCB); setContentView(mPreview); } public void setupScanner() { mScanner = new ImageScanner(); mScanner.setConfig(0, Config.X_DENSITY, 3); mScanner.setConfig(0, Config.Y_DENSITY, 3); int[] symbols = getIntent().getIntArrayExtra(SCAN_MODES); if (symbols != null) { mScanner.setConfig(Symbol.NONE, Config.ENABLE, 0); for (int symbol : symbols) { mScanner.setConfig(symbol, Config.ENABLE, 1); } } } @Override protected void onResume() { super.onResume(); // Open the default ie the first rear facing camera. mCamera = Camera.open(); if(mCamera == null) { // Cancel request if mCamera is null. cancelRequest(); return; } mPreview.setCamera(mCamera); mPreview.showSurfaceView(); mPreviewing = true; } @Override protected void onPause() { super.onPause(); // Because the Camera object is a shared resource, it's very // important to release it when the activity is paused. if (mCamera != null) { mPreview.setCamera(null); mCamera.cancelAutoFocus(); mCamera.setPreviewCallback(null); mCamera.stopPreview(); mCamera.release(); // According to Jason Kuang on http://stackoverflow.com/questions/6519120/how-to-recover-camera-preview-from-sleep, // there might be surface recreation problems when the device goes to sleep. So lets just hide it and // recreate on resume mPreview.hideSurfaceView(); mPreviewing = false; mCamera = null; } } public boolean isCameraAvailable() { PackageManager pm = getPackageManager(); return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA); } public void cancelRequest() { Intent dataIntent = new Intent(); dataIntent.putExtra(ERROR_INFO, "Camera unavailable"); setResult(Activity.RESULT_CANCELED, dataIntent); finish(); } public void onPreviewFrame(byte[] data, Camera camera) { Camera.Parameters parameters = camera.getParameters(); Camera.Size size = parameters.getPreviewSize(); Image barcode = new Image(size.width, size.height, "Y800"); barcode.setData(data); int result = mScanner.scanImage(barcode); if (result != 0) { mCamera.cancelAutoFocus(); mCamera.setPreviewCallback(null); mCamera.stopPreview(); mPreviewing = false; SymbolSet syms = mScanner.getResults(); for (Symbol sym : syms) { String symData = sym.getData(); if (!TextUtils.isEmpty(symData)) { Intent dataIntent = new Intent(); dataIntent.putExtra(SCAN_RESULT, symData); dataIntent.putExtra(SCAN_RESULT_TYPE, sym.getType()); setResult(Activity.RESULT_OK, dataIntent); finish(); break; } } } } private Runnable doAutoFocus = new Runnable() { public void run() { if(mCamera != null && mPreviewing) { mCamera.autoFocus(autoFocusCB); } } }; // Mimic continuous auto-focusing Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() { public void onAutoFocus(boolean success, Camera camera) { mAutoFocusHandler.postDelayed(doAutoFocus, 1000); } }; 

}

CameraPreview.java

 package com.example.sage.appp; import android.content.Context; import android.hardware.Camera; import android.hardware.Camera.AutoFocusCallback; import android.hardware.Camera.PreviewCallback; import android.hardware.Camera.Size; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import java.io.IOException; import java.util.List; public class CameraPreview extends ViewGroup implements SurfaceHolder.Callback { private final String TAG = "CameraPreview"; SurfaceView mSurfaceView; SurfaceHolder mHolder; Size mPreviewSize; List<Size> mSupportedPreviewSizes; Camera mCamera; PreviewCallback mPreviewCallback; AutoFocusCallback mAutoFocusCallback; CameraPreview(Context context, PreviewCallback previewCallback, AutoFocusCallback autoFocusCb) { super(context); mPreviewCallback = previewCallback; mAutoFocusCallback = autoFocusCb; mSurfaceView = new SurfaceView(context); addView(mSurfaceView); // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. mHolder = mSurfaceView.getHolder(); mHolder.addCallback(this); mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public void setCamera(Camera camera) { mCamera = camera; if (mCamera != null) { mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); requestLayout(); } } @Override protected void onMeasure(int widthMeasureSpec, 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 = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); setMeasuredDimension(width, height); if (mSupportedPreviewSizes != null) { mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, 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 (mPreviewSize != null) { previewWidth = mPreviewSize.width; previewHeight = mPreviewSize.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 hideSurfaceView() { mSurfaceView.setVisibility(View.INVISIBLE); } public void showSurfaceView() { mSurfaceView.setVisibility(View.VISIBLE); } public void surfaceCreated(SurfaceHolder holder) { // The Surface has been created, acquire the camera and tell it where // to draw. try { if (mCamera != null) { mCamera.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 (mCamera != null) { mCamera.cancelAutoFocus(); mCamera.stopPreview(); } } private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.1; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // Try to find an size match aspect ratio and size for (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 (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 w, int h) { if (holder.getSurface() == null){ // preview surface does not exist return; } if (mCamera != null) { // Now that the size is known, set up the camera parameters and begin // the preview. Camera.Parameters parameters = mCamera.getParameters(); parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); requestLayout(); mCamera.setParameters(parameters); mCamera.setPreviewCallback(mPreviewCallback); mCamera.startPreview(); mCamera.autoFocus(mAutoFocusCallback); } } 

}

Структура файла: http://imgur.com/hG3skNl

С Gradle 0.7.2+ вы можете поместить свои собственные библиотеки непосредственно в src / main / jniLibs, и он будет работать автоматически. https://stackoverflow.com/a/22488155/1636584 https://stackoverflow.com/a/16993006/1636584

Даже я столкнулся с той же проблемой. Для решения этой проблемы используйте соответствующую библиотеку. Ниже я даю ссылку, это поможет вам. Просто скопируйте файлы библиотеки в каталог вашей библиотеки программ.

https://github.com/ababavali23/barcodeScanner-Libs