我在libs文件夹中有一个库,并且在gradle文件中引用了该库:
provided files('libs/com.symbol.emdk.jar')
当我生成apk时,该应用会启动,但会引发异常:
java.lang.NullPointerException:尝试在以下位置调用虚拟方法'com.symbol.emdk.barcode.Scanner com.symbol.emdk.barcode.BarcodeManager.getDevice(com.symbol.emdk.barcode.BarcodeManager $ DeviceIdentifier)'空对象引用
如果我从本地路径添加库,并生成apk且此方法正常运行,
provided fileTree(include: ['com.symbol.emdk.jar'], dir: '/Users/mocasti/Desktop/EMDK-A-0607095-MAC/SDK/addon-symbol_emdk-symbol-23/libs')
我需要在项目中添加库,但是我不明白为什么应用会引发错误。
代码:
public class MainActivity extends AppCompatActivity implements Runnable, EMDKManager.EMDKListener, Scanner.DataListener, Scanner.StatusListener, View.OnTouchListener {
/**
* Extra name that holds the request to start the scanner
*/
public static final String START_SCANNER_EXTRA = "startScanner";
/**
* The empty string
*/
public static final String EMPTY_STRING = "";
/**
* Last scanned ScanDataCollection. We keep this object to ensure that we discard data when the Scanner scans more than once the same item on a single try.
*/
private ScanDataCollection lastScanned;
/**
* Declare the button for open the scanner upc.
*/
private Button verifierDetailsButton;
/**
* Declare a variable to store ProfileManager object
*/
private ProfileManager mainProfileManager;
/**
* Declare a variable to store EMDKManager object
*/
private EMDKManager emdkManager;
/**
* Allows process Runnable objects associated with a thread's.
*/
private Handler handler;
/**
* This is the scanner.
*/
private Scanner scanner;
/**
* This is the primary object to access the barcode scanning feature.
*/
private BarcodeManager barcodeManager;
/**
* This is a flag for the IP/Device ID button
*/
private boolean isTouched=true;
/**
* This is a starting time for the IP/Device ID button.
*/
private long timeInActionDown=0L;
private Runnable mainTimerExecutor = this;
/**
* It's the first method called when the activity is created.
* The EMDKManager object will be created and returned in the callback.
*
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
verifierDetailsButton = (Button) findViewById(R.id.verifierDetailsButton);
verifierDetailsButton.setOnTouchListener(this);
StoreFormatCustom storeFormatCustom = StoreFormatCustom.getInstance();
VideoActivity.setVideoName(storeFormatCustom.getVideoName());
showMainFragment();
EMDKResults results = EMDKManager.getEMDKManager(getApplicationContext(), this);
}
/**
* Validate if the action is already finished or an item was scanned.
*
* @param intent
*/
public void validateScanAction(Intent intent){
if(intent!=null){
//Check if the intent corresponds to the back action.
//If the intent.getExtras() is not null, it's because the scanning action is over.
//We don't need to do anything if the action is null, because the action already finished.
if(intent.getExtras()!=null){
String upcParameter=intent.getExtras().getString(PriceVerifierConstants.UPC_KEY);
if(upcParameter!=null){
onNewIntent(intent);
}
}
//Checks if you have the right broadcast intent, the action corresponds to EMDK.
//If the intent.getAction() is not null, we can get the upc scanned. We don't need to do
//anything if the action is null.
if(intent.getAction()!=null){
boolean contentAction =intent.getAction().contentEquals(PriceVerifierConstants.EMDK_SAMPLE_RECVR);
if(contentAction){
onNewIntent(intent);
}
}
}
}
/**
* Calls the Scanner Upc activity for put the upc of the item scanned.
*/
public void openScanner() {
Intent intent = new Intent(this, ScannerUpcActivity.class);
startActivity(intent);
}
/**
* Configure the emdk with a specific profile.
* Get the ProfileManager object to process the profiles
* Call processPrfoile with profile name and SET flag to create the
* profile.
*
* The scan validation needs to execute from the onOpened method because
* when the videoActivity start the first time the scanner does not turn off
* the light.
*
* @param emdkManager
*/
@Override
public void onOpened(EMDKManager emdkManager) {
this.emdkManager = emdkManager;
mainProfileManager = (ProfileManager)emdkManager.getInstance(EMDKManager.FEATURE_TYPE.PROFILE);
if(mainProfileManager != null) {
mainProfileManager
.processProfile(PriceVerifierConstants.PROFILE_NAME, ProfileManager.PROFILE_FLAG.SET, new String[1]);
}
Intent intent = getIntent();
intent.putExtra(PriceVerifierConstants.UPC_IS_EMPTY_EXTRA, true);
validateScanAction(intent);
}
/**
* The final call you receive before your activity is destroyed.
* Clean up the objects created by EMDK manager.
*/
@Override
protected void onDestroy() {
handler.removeCallbacks(mainTimerExecutor);
super.onDestroy();
mainProfileManager=null;
if(emdkManager!=null){
emdkManager.release();
emdkManager=null;
}
}
/**
* This function is responsible for getting the data from the intent.
* Disable the scanner when the upc scanned was received.
* @param intentData
*/
private void handleDecodeData(Intent intentData) {
disableScanner();
Intent sendIntent = new Intent(this, PriceVerifierActivity.class);
if(intentData.getExtras() != null) {
String upcScanned = intentData.getStringExtra(PriceVerifierConstants.UPC_TEXT_VIEW_VALUE);
if(upcScanned != null) {
sendIntent.putExtra(PriceVerifierConstants.UPC_TEXT_VIEW_VALUE, upcScanned);
}
}
if(intentData.getAction() != null && intentData.getAction().contentEquals(PriceVerifierConstants.EMDK_INTENT_ACTION)) {
// Get the source of the data
String source = intentData.getStringExtra(PriceVerifierConstants.EMDK_SOURCE_DATA);
// Check if the data has come from the Barcode scanner
if(source.equalsIgnoreCase(PriceVerifierConstants.DATA_SCANNER)) {
// Get the data from the intent
String data = intentData.getStringExtra(PriceVerifierConstants.EMDK_INTENT_DATA);
// Check that we have received data
if(data != null && data.length() > 0) {
sendIntent.putExtra(PriceVerifierConstants.UPC_TEXT_VIEW_VALUE, data);
}
}
}
startActivity(sendIntent);
}
private boolean isAppBeingRestored(Intent intent){
Set<String> categories = intent.getCategories();
boolean hasCategories = categories != null;
return hasCategories && categories.contains(Intent.CATEGORY_LAUNCHER);
}
private void conditionalHandle(Intent intent){
if(!isAppBeingRestored(intent)){
handleDecodeData(intent);
}
}
/**
* Set the upc respect the action (start | finish).
*
* We need to handle any incoming intents, so let override the onNewIntent
* method.
*
*
* @param intent
*/
@Override
public void onNewIntent(Intent intent) {
Bundle dataIntent = intent.getExtras();
String upc = EMPTY_STRING;
boolean turnScannerOn = false;
if(dataIntent != null) {
turnScannerOn = dataIntent.getBoolean(START_SCANNER_EXTRA);
String upcScanned=dataIntent.getString(PriceVerifierConstants.UPC_KEY);
if( upcScanned!= null
&& !upcScanned.isEmpty()) {
upc = upcScanned;
}
}
// As this method is being triggered every time a new Intent occurs, we have to detour
// to enabling the scanner or to read the UPC.
if(turnScannerOn){
enableScanner();
}else if (upc.equals(EMPTY_STRING)
&& !dataIntent.getBoolean(PriceVerifierConstants.UPC_IS_EMPTY_EXTRA)) {
conditionalHandle(intent);
}
}
/**
* This method isn't used for the moment,
* The method is implemented from the EMDKManager interface.
*/
@Override
public void onClosed() {
throw new UnsupportedOperationException();
}
/**
* Remove the call backs in the timer.
*/
@Override
public void onStop() {
handler.removeCallbacks(mainTimerExecutor);
super.onStop();
}
/**
* Thread that count the seconds before change the screen.
*/
@Override
public void run() {
Intent intent = new Intent(MainActivity.this, VideoActivity.class);
intent.putExtra(START_SCANNER_EXTRA, true);
startActivity(intent);
}
/**
* Return to the video when you are in the main activity screen.
*/
@Override
public void onResume(){
super.onResume();
handler = new Handler();
StoreFormatCustom storeFormatCustom = StoreFormatCustom.getInstance();
if(areThereVideos(storeFormatCustom.getVideoName())){
handler.postDelayed(mainTimerExecutor, PriceVerifierConstants.MAX_DELAY_MILLIS);
}
}
/**
* Disable the scanner (DataWedge and EMDK).
*/
public void disableScanner(){
barcodeManager = (BarcodeManager)emdkManager.getInstance(FEATURE_TYPE.BARCODE);
scanner = barcodeManager.getDevice(BarcodeManager.DeviceIdentifier.DEFAULT);
try {
scanner.triggerType = Scanner.TriggerType.HARD;
scanner.disable();
}
catch(ScannerException e) {
EmailContentBuilder emailContentBuilder= new EmailContentBuilder();
ErrorEmailBean errorMailBean= emailContentBuilder.buildEmailContent(e);
SendNotificationTask sendNotificationTask= new SendNotificationTask();
sendNotificationTask.execute(errorMailBean);
}
}
/**
* This method enables the scanner (EMDK only).
*/
public void enableScanner(){
barcodeManager = (BarcodeManager)emdkManager.getInstance(FEATURE_TYPE.BARCODE);
scanner = barcodeManager.getDevice(BarcodeManager.DeviceIdentifier.DEFAULT);
try {
if (scanner.isReadPending()){
scanner.cancelRead();
}
scanner.enable();
scanner.triggerType = Scanner.TriggerType.SOFT_ONCE;
scanner.addDataListener(this);
scanner.addStatusListener(this);
scanner.read();
}
catch(ScannerException e) {
EmailContentBuilder emailContentBuilder= new EmailContentBuilder();
ErrorEmailBean errorMailBean= emailContentBuilder.buildEmailContent(e);
SendNotificationTask sendNotificationTask= new SendNotificationTask();
sendNotificationTask.execute(errorMailBean);
}
}
/**
* Retrieve the upc scanned and it is send to the MainActivity.
* @param scanDataCollection
*/
@Override
public void onData(ScanDataCollection scanDataCollection) {
if(!scanDataCollection.equals(lastScanned)){
lastScanned = scanDataCollection;
String data=scanDataCollection.getScanData().get(0).getData();
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(PriceVerifierConstants.UPC_TEXT_VIEW_VALUE, data.toString());
conditionalHandle(intent);
}
}
/**
* In this method it is not necessary to do anything, but it is necessary to implement it
* from the StatusLister interface, when the scanner is enabled we need to add
* the DataListener and the StatusListener.
*
* @param statusData
*/
@Override
public void onStatus(StatusData statusData) {
throw new UnsupportedOperationException();
}
}
此行引发错误:
scanner = barcodeManager.getDevice(BarcodeManager.DeviceIdentifier.DEFAULT);