3

I have a Cordova plugin which runs a laser scanner on a device, whose Main.java looks like this:

package com.example.plugin;

import org.apache.cordova.*;
import org.json.JSONArray;
import org.json.JSONException;


import java.security.PublicKey;

import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import android.util.Log;

public class Hello extends CordovaPlugin {
    public static final int REQUEST_CODE = 0x0ba7c0de;

    @Override
    public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException {

        if (action.equals("scan")) {
            scan();
            return true;
        } else {
            return false;
        }
    }

    public void scan() {
        Intent intentService = new Intent("com.hyipc.core.service.barcode.BarcodeService2D");
        intentService.putExtra("KEY_ACTION", "UP");

        this.cordova.startActivityForResult((CordovaPlugin) this, intentService, REQUEST_CODE);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
       Log.i("scan", "everything works fine");
    }
}

When I run the plugin, I get this in the error log:

07-11 12:03:33.541: E/AndroidRuntime(5258): FATAL EXCEPTION: main
07-11 12:03:33.541: E/AndroidRuntime(5258): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.ionicframework.curierapp266167/com.hyipc.core.service.barcode.BarcodeService2D}: java.lang.ClassNotFoundException: Didn't find class "com.hyipc.core.service.barcode.BarcodeService2D" on path: DexPathList[[zip file "/data/app/com.ionicframework.curierapp266167-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.ionicframework.curierapp266167-2, /vendor/lib, /system/lib]]
07-11 12:03:33.541: E/AndroidRuntime(5258):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2269)
07-11 12:03:33.541: E/AndroidRuntime(5258):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2395)
07-11 12:03:33.541: E/AndroidRuntime(5258):     at android.app.ActivityThread.access$600(ActivityThread.java:162)
07-11 12:03:33.541: E/AndroidRuntime(5258):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
07-11 12:03:33.541: E/AndroidRuntime(5258):     at android.os.Handler.dispatchMessage(Handler.java:107)
07-11 12:03:33.541: E/AndroidRuntime(5258):     at android.os.Looper.loop(Looper.java:194)
07-11 12:03:33.541: E/AndroidRuntime(5258):     at android.app.ActivityThread.main(ActivityThread.java:5392)
07-11 12:03:33.541: E/AndroidRuntime(5258):     at java.lang.reflect.Method.invokeNative(Native Method)
07-11 12:03:33.541: E/AndroidRuntime(5258):     at java.lang.reflect.Method.invoke(Method.java:525)
07-11 12:03:33.541: E/AndroidRuntime(5258):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
07-11 12:03:33.541: E/AndroidRuntime(5258):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
07-11 12:03:33.541: E/AndroidRuntime(5258):     at dalvik.system.NativeStart.main(Native Method)
07-11 12:03:33.541: E/AndroidRuntime(5258): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.hyipc.core.service.barcode.BarcodeService2D" on path: DexPathList[[zip file "/data/app/com.ionicframework.curierapp266167-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.ionicframework.curierapp266167-2, /vendor/lib, /system/lib]]

I have added this to my AndroidManifest.xml file, but I am pretty certain something's wrong with it.

<activity android:label="@string/share_name" android:name="com.hyipc.core.service.barcode.BarcodeService2D">
    <intent-filter>
        <action android:name="com.hyipc.core.service.barcode.BarcodeService2D" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

EDIT

If i edit my manifest file to this, I get No Activity found to handle Intent error.

<activity android:label="@string/share_name" android:name="com.hyipc.core.service.barcode.BarcodeService2D">
    <intent-filter>
        <action android:name="android.intent.action.LAUNCH" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Also, if I try to start the activity like this:

cordova.getActivity().startService(intentService);

The scanner starts without error, but I don't know how to get its result.

Alexandru Pufan
  • 1,842
  • 3
  • 26
  • 44
  • I think you have missed a dependency.? Can u check your gradle or lib folder? – Raghavendra Jul 11 '16 at 09:09
  • For what exactly should I look? – Alexandru Pufan Jul 11 '16 at 09:51
  • Which library u r using for scanning? – Raghavendra Jul 11 '16 at 09:53
  • It's a native laser scanner, so I can't use a camera library (the device isn't equipped with a camera). Therefore, I tried to develop my own plugin, which uses com.hyipc.core.service.barcode.BarcodeService2D for the intent – Alexandru Pufan Jul 11 '16 at 09:54
  • BarcodeService2D class either needs to be from a library you add inside your app (either a jar or .so if it's a ndk lib) or in an other app installed in your device that you call via intent. – QuickFix Jul 11 '16 at 15:17
  • I'm pretty sure that class is installed on the device. There is another app, called getBarcode, that uses it. The funny thing is that when I try to start the activity like this: cordova.getActivity().startService(intentService); the scanner starts – Alexandru Pufan Jul 13 '16 at 10:01
  • @AlexandruPufan Could be something to do with order and export of android private libraries? Please check out this link - http://stackoverflow.com/questions/16102232/java-lang-runtimeexception-unable-to-instantiate-activity-componentinfo-classn – Gandhi Jul 13 '16 at 13:15
  • You can call `startService` to start it, so the `BarcodeService2D` should be a `Service` ? – suitianshi Jul 14 '16 at 02:07
  • @suitianshi I'm not too good in Java. So a service is different from an activity? How can I get the result back if I use startService? – Alexandru Pufan Jul 14 '16 at 05:47
  • @AlexandruPufan, `Service` and `Activity` are both concepts in Android, not in Java. See my answer plz – suitianshi Jul 14 '16 at 06:17

3 Answers3

3

From the discussion in the comment list we know that BarcodeService2D, is a Service, and you can start the component using startService successfully. Now the question becomes "How can I pass data from my service to an Activity instance" ? There're so many answers in StackOverflow, see this and this. Just google for it.

And for the question "So a service is different from an activity?", the answer is yes. An Activity usually represents a screen in an app. It holds a variety of View, Drawable and many other stuff and you can interact with it directly. A Service is normally used to do a long running task in the background without any UI. For the detail information, see the developer site

Community
  • 1
  • 1
suitianshi
  • 3,300
  • 1
  • 17
  • 34
2

First seems like barcode scanner is a service in your case so use it as a service and register it as a service then seems like you need to create a inner broadcast receiver inside your class like this (from the other post)

 public class BarcodeReceiver extends BroadcastReceiver {
        public void onReceive(Context ctx, Intent intent) {
            if (intent.getAction().equals(ACTION_BARCODE_SERVICE_BROADCAST)) {
                    strBarcode = intent.getExtras().getString(KEY_BARCODE_STR);
                    tvBarcode.setText(strBarcode);
                    strBarcode = "";
            }
        }
    }

Broadcast Receivers they are like guys who does listening and filtering incoming calls.

create a object of this receiver at the top inside activity

 private BroadcastReceiver mReceiver = new BarcodeReceiver();

then register it on resume with a intent filter (so that you don't have to register this in manifest ) and restart service (incase screen on/off)

 @Override
    protected void onResume() {
        super.onResume();
        intentService.putExtra(KEY_ACTION, "INIT");
        this.startService(intentService);

        // register receiver
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_BARCODE_SERVICE_BROADCAST);
        this.registerReceiver(mReceiver, filter);

    }

so notice filter.addAction statement it is like you own unique identity flag so that u can check and match when u get a response inside onreceive() inside your broadcast receiver

at the end when the scanning is done you will be notified inside your broadcast receiver and then you match the identity flag with your unique flag and if it's match then you can fetch the data which will be available with defined key (key-value pair)

public static final String KEY_BARCODE_STR = "key_barcode_string";

don't forget to unregister your receiver in on pause in order to save battery and reduce overhead

 @Override
    protected void onPause() {
        super.onPause();
        //close barcodePower

        this.unregisterReceiver(mReceiver);
    }
Pavneet_Singh
  • 36,884
  • 5
  • 53
  • 68
1

After reading the above discussion I reached to the following points

  1. If BarcodeService2D is an Activity then its manifest declaration should be like this -

        <activity
        android:name="com.hyipc.core.service.barcode.BarcodeService2D"
        android:label="@string/share_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    
  2. If BarcodeService2D is an Service then its manifest declaration should be like this -

    <service android:name="com.hyipc.core.service.barcode.BarcodeService2D">
        <intent-filter>
            /*Your Service specific intent filters should be here*/
        </intent-filter>
    </service>
    
Debu
  • 615
  • 7
  • 21