Native method not found org.opencv.core.mat.n_mat-Android

omarsafwany picture omarsafwany · May 7, 2013 · Viewed 7.1k times · Source

I followed all steps when dealing with Mat including adding it to AsyncTask when calling but still the same error which is native method not found org.opencv.core.mat.n_mat

Here's the code:

package com.example.myfirstapp;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import org.json.JSONException;
import org.json.JSONObject;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Mat;

import com.example.myfirstapp.RegisterMarkerMain.ProcessImage;

import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.util.Base64;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

public class CreateApp extends ListActivity {

    boolean duplicate = false;
    String userID = "";
    Intent manage;
    String image = "";
    Intent refresh;
    CandidatesListAdapter adapter;
    ProcessImage process;
    Mat mRgba;
    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            Log.i("loading libs", "OpenCV loading status " + status);
            switch (status) {
            case LoaderCallbackInterface.SUCCESS: {
                Log.i("loading libs", "OpenCV loaded successfully");

                // Load native library after(!) OpenCV initialization
                System.loadLibrary("native_sample");

            }
                break;
            default: {
                super.onManagerConnected(status);
            }
                break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_create_app);
        manage = new Intent(this, ManageApps.class);
        concurrentTasks();
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            userID = extras.getString("user_id");
            Toast.makeText(CreateApp.this, "User id " + userID,
                    Toast.LENGTH_LONG).show();

        }
        final Spinner spinner = (Spinner) findViewById(R.id.categories_spinner);
        refresh = new Intent(this, ManageApps.class);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
                this, R.array.categories_array,
                android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);

        spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parentView,
                    View selectedItemView, int position, long id) {
                // your code here
                String category = spinner.getSelectedItem().toString();

                Toast.makeText(CreateApp.this,
                        "Category " + category + " selected",
                        Toast.LENGTH_SHORT).show();
                TextView tv = (TextView) findViewById(R.id.question_title);
                tv.setText(category);

            }

            @Override
            public void onNothingSelected(AdapterView<?> parentView) {
                // your code here
            }

        });

        ImageView iv = (ImageView) findViewById(R.id.application_logo);
        registerForContextMenu(iv);
        iv.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View arg0) {
                // TODO Auto-generated method stub
                return false;
            }
        });

        iv.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Toast.makeText(CreateApp.this, "Long click to add image",
                        Toast.LENGTH_LONG).show();
            }
        });

        Button submit = (Button) findViewById(R.id.submit);
        submit.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                EditText et = (EditText) findViewById(R.id.application_name_edit);
                if (et.getText().toString().equals(null)
                        || et.getText().toString().equals("")) {
                    Toast.makeText(CreateApp.this,
                            "App Name can not be empty.", Toast.LENGTH_SHORT)
                            .show();
                } else {
                    if (spinner.getSelectedItem().toString().equals("Select")
                            || spinner.getSelectedItem().toString().equals("")) {
                        Toast.makeText(CreateApp.this,
                                "Cateory must be selected.", Toast.LENGTH_SHORT)
                                .show();
                    } else {
                        new AsyncAppDuplicates().execute();
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        if (duplicate == true) {
                            System.out
                                    .println("Duplicate flag for App Creation inside if "
                                            + duplicate);
                            AlertDialog.Builder builder = new AlertDialog.Builder(
                                    CreateApp.this);
                            builder.setTitle("Warning");
                            builder.setMessage("An application already exists with this name."
                                    + "\n" + "Please choose a different name.");
                            builder.setNegativeButton("Ok",
                                    new DialogInterface.OnClickListener() {
                                        public void onClick(
                                                DialogInterface dialog, int id) {
                                            // if this button is clicked, just
                                            // close
                                            // the dialog box and do nothing
                                            dialog.cancel();
                                        }
                                    });
                            builder.show();
                        } else {
                            concurrentCreate();
                            Toast.makeText(CreateApp.this,
                                    "Created Successfully", Toast.LENGTH_SHORT)
                                    .show();
                            System.out.println("Done");
                            // EditText app = (EditText)
                            // findViewById(R.id.application_name_edit);

                        }
                    }
                }
            }
        });

    }

    @SuppressLint("NewApi")
    private void concurrentTasks() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            new AsyncGetCategories()
                    .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

            System.out.println("getting categories");
        } else {
            new AsyncGetCategories().execute();
        }
    }

    @SuppressLint("NewApi")
    private void concurrentCreate() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            new AsyncCreateApplication()
                    .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

            System.out.println("Creating app");
        } else {
            new AsyncCreateApplication().execute();
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK)) {
            finish();
            manage.putExtra("user_id", userID);
            startActivity(manage);
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.create_app, menu);
        return true;
    }

    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        getMenuInflater().inflate(R.menu.contextmenu, menu);
        menu.setHeaderTitle("Select an Option");
    }


    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_take:
            Toast.makeText(CreateApp.this, "Opening the Camera",
                    Toast.LENGTH_SHORT).show();
            Intent camera = new Intent(
                    android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(camera, 0);
            return true;

        case R.id.menu_choose:
            Toast.makeText(CreateApp.this, "Opening the Gallery",
                    Toast.LENGTH_SHORT).show();
            Intent gallery = new Intent();
            gallery.setType("image/*");
            gallery.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(
                    Intent.createChooser(gallery, "Select Picture"), 1);
            return true;
        }
        return super.onContextItemSelected(item);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        ImageView iv = new ImageView(this);

        switch (requestCode) {
        case 0:
            if (resultCode == RESULT_OK) {
                // Uri selectedImage = data.getData();
                Toast.makeText(this, "Adding Photo From Camera",
                        Toast.LENGTH_LONG).show();
                iv = (ImageView) findViewById(R.id.application_logo);
                Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
                iv.setImageBitmap(thumbnail);
                Intent r = new Intent(this, RegisterMarkerMain.class);
                //startActivity(r);

                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                thumbnail.compress(Bitmap.CompressFormat.PNG, 100, baos); 
                byte[] b = baos.toByteArray();
                image = Base64.encodeToString(b, Base64.DEFAULT);
                //r.putExtra("BitmapImage", image);
                //startActivityForResult(r, 13);
                Toast.makeText(this, "Marker Valid", Toast.LENGTH_LONG).show();
                adapter = new CandidatesListAdapter(this);
                setListAdapter(adapter);

                process = new ProcessImage(this, thumbnail);
                process.execute();
                //call the main layout from xml
                //RelativeLayout mainLayout = (RelativeLayout)findViewById(R.id.create_layout_id);

                //create a view to inflate the layout_item (the xml with the textView created before)
                //View view = getLayoutInflater().inflate(R.layout.layout_item, mainLayout,false);

                //add the view to the main layout
               // mainLayout.addView(view);
            }

            break;
        case 1:
            if (resultCode == RESULT_OK) {
                Toast.makeText(this, "Adding Photo From Gallery",
                        Toast.LENGTH_LONG).show();
                Uri targetUri = data.getData();
                iv = (ImageView) findViewById(R.id.application_logo);
                Bitmap thumbnail = null;
                try {
                    thumbnail = BitmapFactory.decodeStream(getContentResolver()
                            .openInputStream(targetUri));
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                iv.setImageBitmap(thumbnail);
                ByteArrayOutputStream baos=new  ByteArrayOutputStream();
                thumbnail.compress(Bitmap.CompressFormat.JPEG,100, baos);
                byte [] b=baos.toByteArray();;
                try{
                System.gc();
                image=Base64.encodeToString(b, Base64.DEFAULT);
                }catch(Exception e){
                    e.printStackTrace();
                }catch(OutOfMemoryError e){
                    baos=new  ByteArrayOutputStream();
                    thumbnail.compress(Bitmap.CompressFormat.JPEG,50, baos);
                    b=baos.toByteArray();
                    image=Base64.encodeToString(b, Base64.DEFAULT);
                    Log.e("EWN", "Out of memory error catched");
                }
                Toast.makeText(this, "Marker Valid", Toast.LENGTH_LONG).show();
            }
            break;
        }

    }

    public void managePrivacy(View v) {
        Intent privacyIntent = new Intent(this, ManagePrivactActivity.class);
        startActivity(privacyIntent);
    }

    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        Marker o = (Marker) this.getListAdapter().getItem(position);
        Toast.makeText(this, "strength " + o.descriptor.rows(),
                Toast.LENGTH_SHORT).show();
        // TODO: both Image and descriptor should be sent to server combined
        // with location and other info.
        // Descriptor of image is n rows * 64 numbers
    }

    public native void loadCand(long nativeObjAddr, long descriptoradd, int i);

    public native int findMarkersNative(long imgAdd);

    public class ProcessImage extends AsyncTask<Void, Void, ArrayList<Marker>> {


        private Context mContext;
        Bitmap bmp;

        public ProcessImage(Context context, Bitmap bmp) {
            mContext = context;
            mRgba = new Mat();
            this.bmp = bmp;

        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            getListView().setVisibility(View.GONE);
            //loading.setVisibility(View.VISIBLE);

            Utils.bitmapToMat(bmp, mRgba);

        }

        @Override
        protected void onPostExecute(ArrayList<Marker> result) {
            getListView().setVisibility(View.VISIBLE);
            //loading.setVisibility(View.GONE);
            adapter.updateData(result);
            // display

            Utils.matToBitmap(mRgba, bmp);

            //imageView.setImageBitmap(bmp);
            super.onPostExecute(result);

        }

        @Override
        protected ArrayList<Marker> doInBackground(Void... params) {
            ArrayList<Marker> imagesCand = new ArrayList<Marker>();
            // process
            int candCount = findMarkersNative(mRgba.getNativeObjAddr());

            for (int i = 0; i < candCount; i++) {
                Mat cand = new Mat();
                Mat descriptor = new Mat();

                loadCand(cand.getNativeObjAddr(),
                        descriptor.getNativeObjAddr(), i);
                if (descriptor.rows() > 0) {
                    Bitmap bmp3 = Bitmap.createBitmap(cand.cols(), cand.rows(),
                            Bitmap.Config.ARGB_8888);
                    Utils.matToBitmap(cand, bmp3);
                    imagesCand.add(new Marker(bmp3, descriptor));
                }
            }
            return imagesCand;
        }

    }

    private class AsyncCreateApplication extends AsyncTask<String, Void, Void> {
        @Override
        protected Void doInBackground(String... arg0) {
            EditText et = (EditText) findViewById(R.id.application_name_edit);
            String s = et.getText().toString();
            TextView tv = (TextView) findViewById(R.id.question_title);
            String c = tv.getText().toString();
            System.out.println("Category yafanan " + c);
            ServerAPI.createApplication(s, c, userID, image);
            System.out.println("in Background");
            return null;
        }

        protected void onPostExecute(Void result) {
            EditText et = (EditText) findViewById(R.id.application_name_edit);
            refresh.putExtra("app_name", et.getText().toString());
            System.out.println("App created " + et.getText().toString());
            refresh.putExtra("user_id", userID);
            setResult(RESULT_OK, refresh);
            // startActivity(edit);
            startActivity(refresh);
        }

    }

    private class AsyncGetCategories extends AsyncTask<Void, Void, Void> {

        ArrayList<String> al = null;
        ArrayAdapter<String> dataAdapter;
        Spinner category = (Spinner) findViewById(R.id.categories_spinner);

        @Override
        protected Void doInBackground(Void... params) {
            System.out.println("do in background");
            al = ServerAPI.getCategories();
            System.out.println("ArrayList fetched");
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            dataAdapter = new ArrayAdapter<String>(CreateApp.this,
                    android.R.layout.simple_spinner_item,
                    new ArrayList<String>());
            dataAdapter
                    .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            category.setAdapter(dataAdapter);
            dataAdapter.add("Select");
            for (int i = 0; i < al.size(); i++) {
                dataAdapter.add(al.get(i));
                // System.out.println(al.remove(i));
            }

            return;
        }

    }

    private class AsyncAppDuplicates extends AsyncTask<String, Void, Void> {

        @Override
        protected Void doInBackground(String... arg0) {
            EditText et = (EditText) findViewById(R.id.application_name_edit);
            String name = et.getText().toString();

            String s = ServerAPI.checkAppDuplicates(name, userID);
            System.out.println("Checked and " + s);
            if (s.equals("Already there")) {
                duplicate = true;
            } else {
                duplicate = false;
            }
            return null;
        }

    }

}

I've googled so much but I can't figure out what's wrong. Any help would be really appreciated.

Answer

serfe picture serfe · Nov 6, 2013

I solved it writing the following lines where you declare everything for the activity, before onCreate:

static {
    if (!OpenCVLoader.initDebug()) {
        // Handle initialization error
    }
}