Barcode Scanner (ZXing) crashing - java

First off i want to tell you i have done all i can. Followed like 10 tutorials on internet and 10 threads on stacked. Still no success.
I know guys that you recommend using scanning via intent,but in my case its not an option and i need to have it native in my app.
I have downloaded the zxing library (2.1) and followed this tutorial
When i run this code on my Galaxy S3 or Galaxy Tab 10.1 as debug, the program crashes, after freezing for like 20 seconds, when i click the button that should start intent for result: com.google.zxing.client.android.SCAN or com.google.zxing.client.android.CaptureActivity.
Note that i have copied all the resources from Barcode Scanner app like beep sound, xml files and other.
Crash Log
My code is below:
MainActivity.java
package com.example.philipscan;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void scanNow(View view)
{
Log.e("test", "button works!");
Intent intent = new Intent("com.google.zxing.client.android.CaptureActivity");
startActivityForResult(intent, 3);
}
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
Log.e("xZing", "Back");
if (requestCode == 3)
{
if (resultCode == RESULT_OK)
{
String contents = intent.getStringExtra("SCAN_RESULT");
String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
Log.e("xZing", "contents: "+contents+" format: "+format);
// Handle successful scan
}
else if (resultCode == RESULT_CANCELED)
{
// Handle cancel
Log.e("xZing", "Cancelled");
}
}
}
}
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.philipscan"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.flash" android:required="false"/>
<uses-feature android:name="android.hardware.screen.landscape"/>
<uses-feature android:name="android.hardware.wifi" android:required="false"/>
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.philipscan.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="com.google.zxing.client.android.SCAN"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.google.zxing.client.android.CaptureActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="com.google.zxing.client.android.SCAN"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
My SRC folder
I'm very thankful for all the help i can get.

Try to create Intent another way
Intent scanIntent = new Intent("com.google.zxing.client.android.SCAN");
scanIntent.putExtra("SCAN_MODE", "ONE_D_MODE");
then startActivityForResult() as usual. ONE_D_MODE is mode to scan 1D barcodes like Code39.

Remove all this code you copied from our project. It's not necessary, you're not understanding it, and it's not supposed to be reused this way under the license: https://code.google.com/p/zxing/wiki/LicenseQuestions
In particular you are not supposed to copy the manifest, and not allowed to copy the UI.
Instead, it is much simpler, since you seem to be trying to use Intents anyway: https://code.google.com/p/zxing/wiki/ScanningViaIntent

Related

service and manifest files

i wrote this code in android studio , it wont show me the toast message :
here is the manifest file :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/Theme.MyApplication"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".BoradCastReciever"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.AIRPLANE_MODE"/>
</intent-filter>
</receiver>
</application>
</manifest>
and here is the java code class reciever :
package com.mohapp.myapplication;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class BoradCastReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
boolean is_on = intent.getBooleanExtra("air", false);
if (is_on == true) {
Toast.makeText(context, "Air Plane mode is on", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(context, "Air Plane mode is false", Toast.LENGTH_LONG).show();
}
}
}
i am using API 33 with Gradle version 7.5 and Embedd JDK(jdk 11)
In API 30 and plus , it uses the java code more than manifest file and xml files
use onStart and onStop method and add intent inside and use this.register(obj claa of reciever) and unregister on stop method

What forces android activity to be destroyed when launching another activity

I'm trying to add in-app purchases and when I call OpenIabHelper::launchPurchaseFlow function:
I see Google Play purchase window
onStop and onDestroy are executed in my main activity without calls to onActivityResult
So in the end I left with GooglePlay window and my dead app
I tried to start another activity via startActivityForResult and it worked fine
(nothing was destroyed and onActivityResult was called), so it seems that problem is with OpenIAB library
Therefore there's my question:
What can possibly force my activity to be destroyed after calling OpenIabHelper::launchPurchaseFlow ?
It doesn't seem to be system because it has enough memory and as I said startActivityForResult works fine.
Also there's no exceptions being trown so I'm puzzled
Any help would be appreciated
MyActivity.java
public class MyActivity extends AppCompatActivity {
private OpenIabHelper m_helper;
private Boolean m_bOpenIabInitialized = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OpenIabHelper.Options.Builder builder = new OpenIabHelper.Options.Builder()
.addAvailableStores(new GooglePlay(this,null))
.addPreferredStoreName(OpenIabHelper.NAME_GOOGLE)
.setStoreSearchStrategy(OpenIabHelper.Options.SEARCH_STRATEGY_INSTALLER_THEN_BEST_FIT)
.setVerifyMode(OpenIabHelper.Options.VERIFY_SKIP)
.setCheckInventory(false);
m_helper = new OpenIabHelper(this, builder.build());
m_helper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
m_bOpenIabInitialized = result.isSuccess();
}
});
}
public void onListViewItemClicked(String sku, String payload) {
if (m_bOpenIabInitialized == null || !m_bOpenIabInitialized) return;
m_helper.launchPurchaseFlow(this, sku, 10001, null, payload);
}
#Override
public void startActivityForResult(Intent intent, int RequestCode) {
// never reaches here
Log.d(TAG, "startActivityForResult()");
}
#Override
protected void onActivityResult(int RequestCode, int ResultCode, Intent data) {
// never reaches here
Log.d(TAG, "onActivityResult()");
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example" >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="com.android.vending.BILLING" />
<application
android:allowBackup="true"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme" >
<activity
android:name=".MyActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:configChanges="orientation|screenSize|keyboardHidden|screenLayout">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Have you tried changing the activity's launchMode? Maybe the singleTop launch mode will preserve your activity:
<activity
android:name=".MyActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:configChanges="orientation|screenSize|keyboardHidden|screenLayout"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
You can find more about launch modes here:
https://developer.android.com/guide/topics/manifest/activity-element.html#lmode

Keep connectivity broadcast receiver running after application is closed

When I need to use Internet connection and it is not posible I want to set a broadcast receiver which keeps working if the app is closed.
I am using a service for that, but that it is not working. It works fine when the app is on screen or paused but it stops working if I close it. I am not pretty sure if I should use other thing or if I am doing something wrong.
This is my code:
package com.example.ana.exampleapp;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.util.Log;
public class TestsService extends Service {
private static BroadcastReceiver networkChangeReceiver;
private static String TAG = "Service";
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
Log.v(TAG, "Service created");
boolean keep = needTokeepWaiting()
if(!keep)
stopSelf();
}
#Override
public void onDestroy() {
if (networkChangeReceiver != null)
unregisterReceiver(networkChangeReceiver);
networkChangeReceiver = null;
Log.v(TAG, "Service destroyed");
}
private void registerNetworkChangeReceiver() {
networkChangeReceiver = new BroadcastReceiver() {
private String TAG = "NetworkReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "Connection changed received");
boolean keep = needTokeepWaiting()
if(!keep)
stopSelf();
}
};
IntentFilter filter = new IntentFilter(android.net.ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(networkChangeReceiver, filter);
}
}
And my manisfest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.ana.exampleapp">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:windowSoftInputMode="stateHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".RegisterActivity"></activity>
<activity android:name=".FinishRegisterActivity"></activity>
<activity android:name=".TestActivity"></activity>
<activity android:name=".InformationActivity"></activity>
<service android:name=".TestsService"></service>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
And in the TestActivity when it is necessary I do:
Intent service = new Intent(this, TestsService.class);
startService(service);
What I am doing is similar to what it is suggested here, but it doesn't work:
Keep broadcast receiver running after application is closed
I have also tried to do it without a service and registering in the manifest, but It didn't work neither:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.ana.exampleapp">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity"
android:windowSoftInputMode="stateHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".RegisterActivity">
</activity>
<activity android:name=".FinishRegisterActivity" >
</activity>
<activity android:name=".TestActivity">
</activity>
<activity android:name=".InformationActivity" >
</activity>
<receiver android:name=".NetworkChangeReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
I have just found the problem. There is a bug in Android 4.4.x which kills background services when closing the app. I was testing my app in Android 4.4.2. Here there is a detailed explanation:
http://www.androidpolice.com/2014/03/07/bug-watch-stopping-apps-on-android-4-4-2-can-silently-kill-related-background-services-a-fix-is-on-the-way/
So my code was right as I have tried in Android 4.2.2 and it works (I have tried overriding onStartCommand() so maybe that was needed).
If you don't want your service to stop when the app is closed, you should override onStartCommand() method doing something like this:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_REDELIVER_INTENT;
}
You can return START_STICKY or START_REDELIVER_INTENT, whatever works better for you

BroadCastReceiver doesn't work when return button

I have a BroadCastReceiver and since I don't want it to keep working when the application is uninstalled so I removed the declaration of the receiver from the manifest . By doing this the receiver will only work when the application is running . That's good so far but I have a little problem which is if the user clicks "home" button on his device to get back to his device's main screen the receiver works in the background , but when he clicks "back" button the receiver will stop working . I want it to work either the user clicked home button or back button. So how to solve this problem and thanks in advance.
**Note : I'm activating/deactivating the receiver using this code :
private BroadCastReceiver myBroadcastReceiver = new BroadCastReceiver();
#Override
public void onStart() {
super.onStart();
registerReceiver(myBroadcastReceiver, new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION));
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(myBroadcastReceiver);
}
&& my manifest is :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.test"
android:versionCode="9"
android:versionName="8.1" >
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<application
android:allowBackup="true"
android:icon="#drawable/danger"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<intent-filter android:priority="2147483647">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
<activity
android:name="com.aaf.nuclearalert.MainActivity"
android:label="#string/app_name"
android:screenOrientation="landscape"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
*Update 1 :
public void onBackPressed() {
registerReceiver(myBroadcastReceiver, new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION));
}

Writing a SmsReceiver that doesn't let other applications to receive sms

I'm writing an app with a SmsReceiver. I want this class to receive message texts that contains a special word, like "SPY", and don't let other recievers, receive such messages. how can I do it?
here is the receiver class
package com.newidea.repairmycontacts;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import android.telephony.SmsMessage;
public class SmsReceiver extends BroadcastReceiver {
private final static String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
private final String TAG = "SmsReceiver";
#Override
public void onReceive(Context context, Intent intent) {
//onReceiveWithPrivilege(context, intent, false);
if(!intent.getAction().equals(SMS_RECEIVED))
return;
Bundle bundle = intent.getExtras();
if(bundle==null)
return;
Object[] pdus=(Object[]) bundle.get("pdus");
String Body="";
for(int i=0;i<pdus.length;i++)
Body += SmsMessage.createFromPdu((byte[]) pdus[i]).getMessageBody().toString()+"\n";
String Address=SmsMessage.createFromPdu((byte[]) pdus[0]).getOriginatingAddress();
Toast.makeText(context, "Message from "+Address+" : "+Body, Toast.LENGTH_LONG).show();
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.newidea.repairmycontacts"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar" >
<activity
android:name="com.newidea.repairmycontacts.SMSList"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".SmsReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
</application>
You have to set a priority on your intent-filter tag for .SmsReceiver like this:
<receiver android:name=".SmsReceiver">
<intent-filter android:priority="999">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Be aware that this will work with stock messaging app, but some other sms apps use other priorities and may get on top of yours...
After if you want to prevent other apps from receiving the broadcast, you can use:
BroadcastReceiver.abortBroadcast()
Keep in mind that this is fragile specially with other sms apps.

Categories