I would like to integrate zxing into my app.
I'm importing project, set it as library, change target to API 7, download zxing-core-2.2.jar, copy it to /libs and add this jar in Java Building Path as library.
But there are still some errors:
All of them are in switch statements and depend on R.id. for example:
switch (item.getItemId()) {
case R.id.menu_share:
Eclipse error description:
case expressions must be constant expressions
there is a info dialog:
Any idea what I'm doing wrong or how to fix it?
As explained in the dialog you have shown, R.id.menu_settings is now "no longer constant", which means it cannot be used in a switch. the dialog also provides the solution, instead of
switch (item.getItemId()) {
case R.id.menu_share:
//do something
break;
case xxx:
...
}
You should do this:
if(item.getItemId()==R.id.menu_share) {
//do something
} else if (item.getItemId()==xxx) {
//do something
}
Just follow the instruction and you should be fine.
The problem is the source of zxing is not intended to be used as a Library..
Please see the answer by Sean in the below thread.
Zxing project as library in a project won't build
I tried bridling my app within this CaptureActivity project adding my activity and resources and modifying its manifest File accordingly.
Related
The Code A is from CameraX project, you can see source code.
Android Studio will display "only be called from with the same library group" when I remove #SuppressLint("RestrictedApi"), you can see Image 1.
Why can't I remove #SuppressLint("RestrictedApi") in Code A ? What deos a restriction API mean?
Code A
#SuppressLint("RestrictedApi")
private fun updateCameraUi() {
...
// Listener for button used to switch cameras
controls.findViewById<ImageButton>(R.id.camera_switch_button).setOnClickListener {
lensFacing = if (CameraX.LensFacing.FRONT == lensFacing) {
CameraX.LensFacing.BACK
} else {
CameraX.LensFacing.FRONT
}
try {
// Only bind use cases if we can query a camera with this orientation
CameraX.getCameraWithLensFacing(lensFacing)
// Unbind all use cases and bind them again with the new lens facing configuration
CameraX.unbindAll()
bindCameraUseCases()
} catch (exc: Exception) {
// Do nothing
}
}
}
Image 1
There have been breaking changes in the library since the tutorial was made.
Reverting the package version to 1.0.0-alpha06, same as the tutorial, solves the problem.
These are issues with the library that don't affect your code.
In several code examples using these APIs there is often a #SuppressLint("RestrictedApi") in the file hiding the warning.
The projects should still compile and run as they should, although you must make sure that you are using the correct dependency version. The APIs are changing quite frequently still, and if you're referencing an example it might be using an older version which has since changed.
Your best bet is to look directly at the source code and if the method you are calling is declared as public then you probably won't have a problem.
i am using dexguard to secure my app. Recently i updated the dexgaurd version
from 8.0.1 to 8.2.15. Earlier everything is working fine before the update. But with the version 8.2.15 when i apply dexguard, onCick method does not works in one of fragment SettingsFragment, for all of the other Fragments it works fine. However the code and method of implementing onClick() is same for all Fragments. But for SettingsFragment it's not working. Please help.
Here is my onClick method in SettingsFragment
View.OnClickListener onClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.relSignOut:
mCallback.doSignOut();
break;
// case R.id.relEditProfile:
// loadManageProfile();
// break;
case R.id.btn_edit_profile:
loadManageProfile();
break;
case R.id.relDynamicFxRate:
parent.startSetExchangeAlertActivity();
break;
}
}
};
Thanks in Advance
You should exclude obfuscation of onClick methods like this:
-keepclassmembers class * {
public void onClick (android.view.View);
}
(Converting my comment to answer)
Please kick off the switch statement and replace it with if-else. May seem bit unscientific and illogical, but I worked for me many times.
I don't know if it's a possible bug in the compiler or in Android or not, but sometimes rejecting switch statement only doesn't help. Then I've to replace view.getId() with view.getPosition() and check by order or something like this to make it work anyway.
From T.Neidhart's comment: The reason it fails is probably due to resource optimization which remaps resource IDs. Normally these remapped resource IDs get replaced everywhere in the code, but it might go wrong in case of switch statements. You can disable resource optimization like that: -optimizations resource/compaction –
My old app has one simple menu on the main activity. It has only a few simple options, for instance "About" causing a popup with some info about the app.
It works perfectly on emulator Nexus One (API23), because there is an emulated physical menu button.
However, on most modern phones, there is no button, which means that my menus cannot be accessed.
I actually vaguely remember running it on a phone years ago which didn't have a menu button, yet somehow one could still access the menus. I may remember wrong.
(I started digging into this some days ago, and started modifying my code, the main activity inheriting from something more posh than Activity, which then caused some older API versions to be left out - and things quickly spun out of control. After hours of "maven gradle settings" and "Support Library" stuff and many pages of "AAPT2 errors" and messing up my whole system trying to fix that, I had to throw everything away and get a fresh clone from the repo. Fortunately I could also repair the other changes I had made to the system.)
How does one convert an old-style app menu to work on modern phones? It doesn't have to be fancy.
/** Setup menu */
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
/** Handle menu clicks */
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.action_about:
final SpannableString s =
new SpannableString(getApplicationContext().getText(R.string.about));
Linkify.addLinks(s, Linkify.ALL);
AlertDialog d = new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_info)
.setTitle("About")
.setMessage(s)
//.setView(message)
.show();
((TextView)d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
return true;
default:
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_info)
.setTitle("Currently not used.")
.show();
return super.onOptionsItemSelected(item);
}
}
I'll admit that I no longer understand all the details above from years ago.. it worked, so I never paid it much attention. It looks a bit wordy... probably there are simpler ways to do it.
This is menu/main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"/>
<item
android:id="#+id/action_about"
android:orderInCategory="3"
android:title="About"/>
<item
android:id="#+id/action_manual"
android:orderInCategory="4"
android:title="Manual"/>
</menu>
Maybe there is some "theme" to just add somewhere that makes the menu button show up somewhere on the screen, and that's that? (I know I am optimistic. :))
Everything looks fine.
I think your problem is because you are extending Activity.
change Activity to AppComatActivity.
and change your appThem to android:theme="#style/Theme.AppCompat.Light.DarkActionBar"
Note:
To use the AppCompatActivity, make sure you have the Google Support Library downloaded (you can check this in your Tools -> Android -> SDK manager). Then just include the gradle dependency in your app's gradle.build file:
compile 'com.android.support:appcompat-v7:27.0.2'
SOLUTION:
The only way to a solution that I could find was to create a completely new project with default settings in the latest Android Studio. This gives a "latest fashion" setup. Then I moved code in from the old project manually.
Everything now works perfectly!
ISSUES / REASONS:
As mentioned in the comment section above, every attempt I made to modernize the code resulted in a maze of problems. It was an old project, from way back when Android Studio was not even in Beta stage. Hence, it was based on Eclipse. The current Android version back then was Jelly Bean (Kitkat was just released).
In summary, we had an ancient project based on an older IDE. Perhaps it would be doable to convert a modern Eclipse project into Android Studio. Perhaps it would be doable to convert an older AS project into a modern one. However, performing both these major jumps at the same time was too great a challenge for me.
Another issue which has nothing to do with the old code, but which confused the matter greatly is that something called AAPT2 currently for whatever reason assumes american characters only in the search path to the .gradle directory. I use the word "assumes", because if the characters are anything else, you get pages of errors in the build log. None of the errors point very clearly to the reason.
AFAIK I don't even use AAPT2! After some sleepless nights, I solved it by changing the global setting in Android Studio to simply use another path.
I tried to make my own small calculator, but I don't want to make all the business logic by myself. So I tried to use the javax.script since I heard that the javax.script needs a real JVM and is a JavaScriptParser. Then, I searched for other libraries with the functions I needed and found the project "exp4j". First, I made a small normal Java Project with JDK 1.7, and yes, it works with the source code:
public static void main(String[] args) throws UnknownFunctionException, UnparsableExpressionException {
ExpressionBuilder builder=new ExpressionBuilder("34*2");
Calculable calc=builder.build();
System.out.println(calc.calculate());
}
Then, I tried the same code in my model (MVC Pattern) of my calculator:
public void berechnen() throws UnknownFunctionException, UnparsableExpressionException {
ExpressionBuilder builder=new ExpressionBuilder("34*2");
Calculable calc=builder.build();
setErgebnis(calc.calculate());
}
But every time I got the same exception:
"AndroidRuntime(630): java.lang.VerifyError",
after I started the app. I can't click on the button that runs the method berechnen() because the app crashes after I start it.
I'm confused why my program doesn't work. When I delete all imports of exp4j and delete the source for the calculation, my calculator works fine.
My only idea is that the exp4j libaries is using a class or method that does not exist in Android.
Thank you.
You may have include jars twice, check once in libs folder and libraries in properties, I have faced same in the past What you need to do is to
Remove that in the libraries and paste freshly in your res/lib folder of android application project and then clear your project
This question has also been asked by someone on the Android Developers Google Group (link), but it does not have an answer...
I recently removed the v4 support library from my Android project in Eclipse, because my application only targets Android 4.0 (Ice Cream Sandwich) and up. I'm now going through all the support library references that are giving me errors.
One in particular is NavUtils, which seems to be a support library class used in Activity navigation. Example:
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
What is the equivalent of NavUtils when not using the support library?
Look at the source code of NavUtils, if necessary just copy it to your project. It just gets the parent activity set in the manifest and starts it.
I found #Nikolay's approach to be the best if you don't want to have the whole android v4 support library in your project.
This is the list of classes you should copy into your project:
NavUtils
NavUtilsJB
IntentCompat
IntentCompatHoneycomb
IntentCompatIcsMr1
Android version from Jelly Beans have the NavUtils incorporated into the Activity class.
There is no need to handle the case : android.R.id.home in onOptionsItemSelected().
OR you can just return false for this case in onOptionsItemSelected().
Here is this simplest answer I could find, and what I did in my code:
Simply replace:
NavUtils.navigateUpFromSameTask(this);
with:
navigateUpTo(getParentActivityIntent());
Hope this helps!