I'm trying to implement a barcode reader.
https://www.youtube.com/watch?v=wfucGSKngq4&list=PLYBH5YZZegIf1DzLtuFmeDFqHYsfw1h1I&index=7&t=232s
I've followed this tutorial, and almost everything works fine. The only issue I have is that it always opens in landscape screen, and I have absolutely no clue what I do wrong.
butonScanare.setOnClickListener(v -> {
IntentIntegrator integrator = new IntentIntegrator(activity);
integrator.setCaptureActivity(CaptureActivity.class);
integrator.setOrientationLocked(false);
integrator.setDesiredBarcodeFormats(IntentIntegrator.ALL_CODE_TYPES);
integrator.setPrompt("Scanare");
integrator.initiateScan();
});
Any clue what I'm doing wrong?
Just add this in your AndroidManifest.xml file
<activity
android:name="com.journeyapps.barcodescanner.CaptureActivity"
android:screenOrientation="portrait"
tools:replace="android:screenOrientation"
android:stateNotNeeded="true"/>
Related
I am working on an well-being app that shuts your phone up for a given period of time (eg. 30min, 1hr, 1.5hr)
In this state user can only see a screen with remaining time on it and cannot
Access QS tiles
Access Volume panel
Navigate out of the Activity
something similar to Oneplus
Zen mode
things i have thought of for doing this
Killing the SystemUI process.(by doing so the QS and volume panel
would be dealt with most probably, maybe need root for that tho?
also SystemUI automatically restarts itself, quite stubborn)
Making app a launcher Dynamically?(technically you can't navigate
out of a launcher and on reboot you come back to it)
how can I get around accomplishing this? any ideas?
Making application the default launcher of the phone is more practical solution to what you're trying to achieve. I've done this previously in a Flutter application which was going to be installed on kiosk devices to get orders from customers and it worked perfectly. It's a bit tricky to make it work and there's lots of things to do. Here is a list of things I did back then:
Use FLAG_SHOW_WHEN_LOCKED flag to the window to bypass the lock screen.
Inside of onResume add FLAG_FULLSCREEN flags to hide the status bar.
Make your MainActivity launcher by adding LAUNCHER category to in AndroidManifest.xml. Also you can add other attributes I used (Search for them if you don't know what are they supposed to do).
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:excludeFromRecents="true"
android:hardwareAccelerated="true"
android:launchMode="singleInstance"
android:showOnLockScreen="true"
android:showWhenLocked="true"
android:theme="#style/LaunchTheme"
android:turnScreenOn="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Listen for window focus changes in your MainActivity and bring your application to front if it lost the focus.
private fun moveToFront() {
val closeDialog = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
sendBroadcast(closeDialog)
(activity.applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager)
.moveTaskToFront(activity.taskId, ActivityManager.MOVE_TASK_WITH_HOME)
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (!hasFocus) {
moveToFront()
}
}
I was also checking if my application is the default launcher.
private fun isAppDefault(): Boolean {
val intent = Intent(Intent.ACTION_MAIN)
intent.addCategory(Intent.CATEGORY_HOME)
val res: ResolveInfo = packageManager.resolveActivity(intent, 0)
return res.activityInfo != null && (packageName
== res.activityInfo.packageName)
}
And you're gonna need to communicate between Flutter and the platform using MethodChannel to enable and disable force mode and get the state of the application.
I have 2 product flavor. Let's say the example like this:
productFlavors {
free {
applicationId 'com.free.android'
}
premium {
applicationId 'com.premium.android'
}
My problem is when i use
Intent resultIntent = new Intent(this, ExpiryListActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(ExpiryListActivity.class);
stackBuilder.addNextIntent(resultIntent);
The problem happened when stackBuilder.addParentStack(ExpiryListActivity.class)
The first app which used the productFlavor free doesn't cause android.content.pm.PackageManager$NameNotFoundException error.
But the second app which used the productFlavor premium it causes android.content.pm.PackageManager$NameNotFoundException.
Then i read the docs that stackBuilder.addParentStack(<Class>) Add the activity parent chain as specified by manifest . How to solve this problem?
TL;DR
change your metadata as
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="originalPackageName.ui.MainActivity" />
The basic problem is that gradle is expanding the package name for the parent activity class that you wrote in the metadata.
In case of your free product flavor it tries to find a class at location com.free.android.ui.MainActivity
And in case of your paid flavor it tries to find a class at location com.premium.android.ui.MainActivity
But gradle actually does not restructure the packages when you mention different applicationId's for your product flavors and the class is still located at originalPackageName.ui.MainActivity and hence the NameNotFoundException
where originalPackageName is a placeholder for the package name you started your project with.
Looks like i found it. On AndroidManifest.xml
<activity
android:name=".ui.ExpiryListActivity"
android:label="#string/voucher_expiry_list"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar.Slidable" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.MainActivity" />
</activity>
I replace the meta-data name by:
<activity
android:name=".ui.ExpiryListActivity"
android:label="#string/voucher_expiry_list"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar.Slidable" >
<meta-data
android:name=".ui.ExpiryListActivity"
android:value=".ui.MainActivity" />
</activity>
It works, but when pressing back it cannot return to MainActivity. But, I know if this is not the best solution. Please let me know if there is another better solution.
NB: This seems only happened on Android Lollipop (5.0)
I'm using the new google plays service: Barcode detector, for this porposue I'm following this tutorial : https://search-codelabs.appspot.com/codelabs/bar-codes
But when I run the application on my real device(Asus Nexus 7), the text view of the app always is showing me "Couldn't set up the detector" and i don't know how to make it work >< ...
Here some code for fast debugging:
public class DecoderBar extends Activity implements View.OnClickListener{
private TextView txt;
private ImageView img;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_decoder);
Button b = (Button) findViewById(R.id.button);
txt = (TextView) findViewById(R.id.txtContent);
img = (ImageView) findViewById(R.id.imgview);
b.setOnClickListener(this);
}
// [...]
#Override
public void onClick(View v) {
Bitmap myBitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(),R.drawable.popi);
img.setImageBitmap(myBitmap);
BarcodeDetector detector = new BarcodeDetector.Builder(getApplicationContext())
.setBarcodeFormats(Barcode.DATA_MATRIX | Barcode.QR_CODE)
.build();
if(!detector.isOperational()){
// Always show this message, so, never is operational!
txt.setText("Could not set up the detector!");
return;
}
Frame frame = new Frame.Builder().setBitmap(myBitmap).build();
SparseArray<Barcode> barcodes = detector.detect(frame);
Barcode thisCode = barcodes.valueAt(0);
txt.setText(thisCode.rawValue);
}
}
It looks like the first time barcode detector is used on each device, some download is done by Google Play Services. Here is the link:
https://developers.google.com/vision/multi-tracker-tutorial
And this is the excerpt:
The first time that an app using barcode and/or face APIs is installed
on a device, GMS will download a libraries to the device in order to
do barcode and face detection. Usually this is done by the installer
before the app is run for the first time.
I had this problem now. You can't update the Google Play Services. After I used the same as on the tutorial it works.
compile 'com.google.android.gms:play-services:7.8+'
Here is what was my case.
I was using BarcodeDetector for decoding QR codes from imported images. On 4 my testing devices it was working fine. On one was not reading anything from bitmap. I thought this might be incompatibility with android 5.0 but this was not the case. After hours of investigation I finally noticed that detector.isOperational(); returns false. The reason was:
The first time that an app using barcode and/or face APIs is installed on a device, GMS will download a libraries to the device in order to do barcode and face detection. Usually this is done by the installer before the app is run for the first time.
I had wi-fi off on that testing device. After turning it on and relaunching app, detector became operational and started decoding bitmaps.
To use the API, it's necessary to have internet connection, I had connection to my ADSL but not resolved DNS. Fixing that problem make my app works
Sometimes detector dependencies are downloaded when the app runs for the first time and not when the app installs. I too faced the same issue, the problem is either your network connection is weak or you don't have enough storage for download say 10% of the total space though it does not take that much space but downloads from Google Play Services does require good amount of storage and don't forget to clear cache(Simple check try to update any application from playstore). Refer this Github thread for more information.
Check your storage! make sure it is over 10%
That fixed my problem, and I answered it here too...
https://stackoverflow.com/a/43229272/6914806
you must not forget this:
add this to your AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.gms.vision.DEPENDENCIES"
android:value="ocr"/>
I have just opened my code from a few weeks off and now it doesn't seem to work. I have a splash screen on open, which then moves to the home screen. The splash screen works, but when trying to move to the home page it falls over saying No Class Def Found. What does this mean and how can i fix it?
It says the problem is found with the below code which is in the splash screen class:
public void run()
{
//Finish the splash activity so it can't be returned to.
SplashScreen.this.finish();
// Create an Intent that will start the main activity.
Intent mainIntent = new Intent(SplashScreen.this, HomeScreen.class);
SplashScreen.this.startActivity(mainIntent);
}
please place HomeScreen in manifest file
<activity android:name=".HomeScreen"
android:label="#string/app_name">
</activity>
So what happened was I updated the Android SDK and apparently there have been a few problems with this, one being changing lib to libs. What I did was removed the activity and re-added. Thanks arcastro.
So if anyone has this problem from 16->17, check the activity's in the manifest file, and the lib folder
does not compile. Indeed: even in 1.5, this api, getIntent(), is already listed as deprecated.
The error message I get complains that getIntent() does not return a String, but setCurrentTab() expects a string.
If I guess and change the line to read:
"tabHost.setCurrentTab(1); // was setCurrentTab(getIntent())",
then it compiles, builds, but does not run. I get the "stopped unexpectedly" error message from the emulator. I cannot even get Log.d to output, so it seems that it stops 'unexpectedly' very early.
So the first and main question is: what is the correct fix to "tabHost.setCurrentTab(getIntent())" in the final line of OnCreate() in http://developer.android.com/resources/tutorials/views/hello-tabwidget.html?
The second and simpler question is: did I guess right in replacing 'mTabHost' with tabHost in the one place where that occurs?
Here's the problems and fixes for that particular tutorial:
Step 2: When creating your activities, if you do not create them through the manifest then you'll need to add them to the manifest manually.
Add these lines to AndroidManifest.xml:
<activity android:name=".AlbumsActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar">
</activity>
<activity android:name=".ArtistsActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar">
</activity>
<activity android:name=".SongsActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar">
</activity>
Step 3: You are only instructed to create the ic_tab_artists.xml file. You'll need to create one for ic_tab_songs.xml and ic_tab_albums.xml as well. You can just duplicate the ic_tab_artists.xml (or change the HelloTabView.java tab specs to use the artists.xml file for each tab).
Step 4: The third to last line under /res/layout/main has a typo (a ; instead of a :)
android:padding="5dp" />
</LinearLayout>
</TabHost>
Step 6: There is a typo that uses calls mTabHost instead of tabHost. Change it.
As already cited the getIntent() function on the last line isn't appropriate. I just call the tab based on it's id. eg:
tabHost.setCurrentTabByTag("albums");
At the Informal Android Meetup, I was able to confirm that my first guess was in the ballpark: the line as printed in the tutorial really is wrong, it should be replaced with something like, "tabHost.setCurrentTab(0); // was setCurrentTab(getIntent())".
There was one other major omission I had to fix before I could get the HelloTabWidget Tutorial to run: Albums|Artists|SongsActivity all had to be added to the manifest, manifest.xml. Somehow, the tutorial instructions managed to omit mention of this requirement.