2015-01-29 39 views
5

Mam problem z moją aplikacją do skanowania kodów kreskowych, kod działa idealnie, dopóki nie przetestuję przycisku Skanowania, w tym momencie ulega awarii i pojawia się następujący błąd:Android Studio nie może znaleźć "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) 

są to zajęcia używam:

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 i.e. 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); 
    } 
} 

}

Struktura

Plik: http://imgur.com/hG3skNl

+0

Co to jest libiconv.so? (To ty powiedziałeś Androidowi, żeby próbował załadować libiconv.so). – immibis

+1

Jest to część biblioteki ZBar, nie jestem do końca pewien, co robi. –

+0

Udało ci się to rozwiązać? – LefterisL

Odpowiedz

0

Nawet ja miałem do czynienia z tym samym problemem. Użyj odpowiedniej biblioteki, aby rozwiązać ten problem. Poniżej podaję link, który ci pomoże. po prostu skopiuj pliki biblioteki do katalogu biblioteki programów.

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