How do I change the package name while including native libraries - android

I have an Android project based upon the fantastic code available at http://ikaruga2.wordpress.com/2011/08/10/video-live-wallpaper-part-4/. Essentially, this app is a live wallpaper that uses FFMpeg to read a video file frame by frame and play it out to screen using GLWallpaperService.
I downloaded the code and was able to get it running successfully on my phone. I made several changes and then tested again on several devices and all worked fine. This evening I tried to change the package name from "ffvideolivewallpaper.frankandrobot.com" to "com.nightscapecreations.orionkeysfree". I did a search and replace in the java, c, and xml files to replace them. I also modified the c file to replace "Java_ffvideolivewallpaper_frankandrobot_com_NativeCalls" with "Java_com_nightscapecreations_orionkeysfree_NativeCalls". However, when I run the app on my phone now I receive this error:
09-30 12:53:44.911: E/AndroidRuntime(24237): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
09-30 12:53:44.911: E/AndroidRuntime(24237): at dalvik.system.NativeStart.main(Native Method)
09-30 12:53:44.911: E/AndroidRuntime(24237): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1936]: 145 could not load needed library '/data/data/ffvideolivewallpaper.frankandrobot.com/lib/libavutil.so' for 'libavcore.so' (load_library[1091]: Library '/data/data/ffvideolivewallpaper.frankandrobot.com/lib/libavutil.so' not found)
09-30 12:53:44.911: E/AndroidRuntime(24237): at java.lang.Runtime.loadLibrary(Runtime.java:370)
09-30 12:53:44.911: E/AndroidRuntime(24237): at java.lang.System.loadLibrary(System.java:535)
09-30 12:53:44.911: E/AndroidRuntime(24237): at com.nightscapecreations.orionkeysfree.NativeCalls.<clinit>(NativeCalls.java:64)
09-30 12:53:44.911: E/AndroidRuntime(24237): ... 13 more
I'm assuming there's a reference to the old package name that I'm missing somewhere, but I can't find anything with Eclipse's file search. Eclipse is managing the NDK and compiling all the libraries and c code for me. So far I've tried:
Doing a clean build
Restarting Eclipse
Removing everything in the libs directory and building again
The native calls file that is erroring looks like this:
package com.nightscapecreations.orionkeysfree;
public class NativeCalls {
//ffmpeg
public static native void initVideo();
public static native void loadVideo(String fileName); //
public static native void prepareStorageFrame();
public static native void getFrame(); //
public static native void freeConversionStorage();
public static native void closeVideo();//
public static native void freeVideo();//
//opengl
public static native void initPreOpenGL(); //
public static native void initOpenGL(); //
public static native void drawFrame(); //
public static native void closeOpenGL(); //
public static native void closePostOpenGL();//
//wallpaper
public static native void updateVideoPosition();
public static native void setSpanVideo(boolean b);
//getters
public static native int getVideoHeight();
public static native int getVideoWidth();
//setters
public static native void setWallVideoDimensions(int w,int h);
public static native void setWallDimensions(int w,int h);
public static native void setScreenPadding(int w,int h);
public static native void setVideoMargins(int w,int h);
public static native void setDrawDimensions(int drawWidth,int drawHeight);
public static native void setOffsets(int x,int y);
public static native void setSteps(int xs,int ys);
public static native void setScreenDimensions(int w, int h);
public static native void setTextureDimensions(int tx,
int ty );
public static native void setOrientation(boolean b);
public static native void setPreviewMode(boolean b);
public static native void setTonality(int t);
public static native void toggleGetFrame(boolean b);
//fps
public static native void setLoopVideo(boolean b);
static {
System.loadLibrary("avcore");
System.loadLibrary("avformat");
System.loadLibrary("avcodec");
//System.loadLibrary("avdevice");
System.loadLibrary("avfilter");
System.loadLibrary("avutil");
System.loadLibrary("swscale");
System.loadLibrary("video");
}
}
How do I resolve this error? What else needs done when changing the package name? I'll need to do this many times in the future.
EDIT:
It looks like I was looking in the wrong place. The developer of the original version of the code pointed out that there is a package name passed in when compiling the ffmpeg libraries. He was nice enough to compile a new version for me with my package name and the wallpaper worked perfectly. We tried a compile without the package name, but when added to the app it just resulted in:
10-04 08:20:57.414: E/AndroidRuntime(19139): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1936]: 145 could not load needed library 'libavutil.so' for 'libavcore.so' (load_library[1091]: Library 'libavutil.so' not found)
I'm guessing that I'll just need to compile a new version each time I make a new wallpaper. For those who are trying to do the same, I'd like to point out that the version of ffmpeg used in this project requires version 5 of the ndk; version 9 will not compile it correctly.
I've accepted an existing answer instead of adding my own as it does answer the original intent of my question, even if it didn't resolve this specific issue, and I think it could be helpful to other new developers.

If using Eclipse, the proper way to rename the package is to do the following: Right click on project -> Android Tools -> Rename Application Package.

The easiest change would be not to move the NativeCalls class to the new package. This may cause few import statements in Java files that use this class, but your C code can be kept unchanged. You can even use it without recompile.

Related

Android Callable Wrapper fails to buid for Crosswalk project

I have created a binding project for the crosswalk project. It has created ACW code that fails to build
package mono.org.xwalk.core.internal;
public class XWalkSettingsInternal_ZoomSupportChangeListenerImplementor
extends java.lang.Object
implements
mono.android.IGCUserPeer,
org.xwalk.core.internal.XWalkSettingsInternal.ZoomSupportChangeListener
{
static final String __md_methods;
static {
__md_methods =
"n_onGestureZoomSupportChanged:(ZZ)V:GetOnGestureZoomSupportChanged_ZZHandler:Org.Xwalk.Core.Internal.XWalkSettingsInternal/IZoomSupportChangeListenerInvoker, MethodCRM.Crosswalk\n" +
"";
mono.android.Runtime.register ("Org.Xwalk.Core.Internal.XWalkSettingsInternal+IZoomSupportChangeListenerImplementor, MethodCRM.Crosswalk, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", XWalkSettingsInternal_ZoomSupportChangeListenerImplementor.class, __md_methods);
}
public XWalkSettingsInternal_ZoomSupportChangeListenerImplementor () throws java.lang.Throwable
{
super ();
if (getClass () == XWalkSettingsInternal_ZoomSupportChangeListenerImplementor.class)
mono.android.TypeManager.Activate ("Org.Xwalk.Core.Internal.XWalkSettingsInternal+IZoomSupportChangeListenerImplementor, MethodCRM.Crosswalk, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "", this, new java.lang.Object[] { });
}
public void onGestureZoomSupportChanged (boolean p0, boolean p1)
{
n_onGestureZoomSupportChanged (p0, p1);
}
private native void n_onGestureZoomSupportChanged (boolean p0, boolean p1);
java.util.ArrayList refList;
public void monodroidAddReference (java.lang.Object obj)
{
if (refList == null)
refList = new java.util.ArrayList ();
refList.add (obj);
}
public void monodroidClearReferences ()
{
if (refList != null)
refList.clear ();
}
}
This is the build error that I have received.
/Users/xxxxx/Integration/Mobile/MethodCRM/Droid/obj/Debug/android/src/mono/org/xwalk/core/internal/XWalkSettingsInternal_ZoomSupportChangeListenerImplementor.java(48,48): Error: error: ZoomSupportChangeListener is not public in XWalkSettingsInternal; cannot be accessed from outside package
org.xwalk.core.internal.XWalkSettingsInternal.ZoomSupportChangeListener
(MethodCRM.Droid)
It seems like the compiler is complaining that org.xwalk.core.internal.XWalkSettingsInternal.ZoomSupportChangeListener is private interface but XWalkSettingsInternal_ZoomSupportChangeListenerImplementor is a public class. How do I resolve this error?
Update:
I have tried removing XWalkSettingsInternal and XWalkSettingsInternal.ZoomSupportChangeListener in Metadata.xml but that didn't resolve the issue.
<remove-node path="/api/package[#name='org.xwalk.core.internal']/class[#name='XWalkSettingsInternal']" />
<remove-node path="/api/package[#name='org.xwalk.core.internal']/interface[#name='XWalkSettingsInternal.ZoomSupportChangeListener']" />
I have tried the CrossWalk wrapper in this GitHub project https://github.com/philieu/XamarinFormsXWalkViewTest and it works, so maybe you could look at that to see what you are doing differently?
Update: I looked through the CrossWalk source and I don't see anywhere that XWalkSettingsInternal is exposed publicly by other classes, so I would just remove that node completely.
This link may be helpful http://forums.xamarin.com/discussion/12627/java-binding-member-cannot-be-accessed-from-outside-package
Please note that when you look through the source code of Crosswalk and see some classes named xxInternal.java in the package org.xwalk.core.internal, these classes are NOT externally exposed interface.
When you building source code of Crosswalk, there is a script that translates org.xwalk.core.internal.xxInternal.java to org.xwalk.core.xx.java automatically, which is the final interface to the developers. Although there is a one-to-one correspondence between this pair of files, they are not exactly the same. Only the method marked by #XWalkAPI in xxInternal.java will remain in xx.java.
You can check the final interface via official API docs, or by decompiling xwalk_core_library.jar, which could be found in the AAR file you're using.

React Native Android Native UI Components doesn't find #ReactProps

i'm trying to implement my first react native UI component, i followed the Facebook tutorial and it should be easy but i have some strange problem
public class CameraViewManager extends SimpleViewManager<CameraPreview> {
public static final String REACT_CLASS = "RCTCameraView";
#Override
public String getName() {
return REACT_CLASS;
}
#Override
public CameraPreview createViewInstance(ThemedReactContext context) {
return new CameraPreview(context);
}
#ReactProp(name = "test")
public void setTest(CameraPreview view, #Nullable String test){
Log.i("TESTWD", test);
}
}
This is the ViewManager i'm using and to me it seems correct. The first problem is that android studio doesn't find #ReactProp and it doesn't compile. The second problem is that if i remove that method everything compile but when i use this component nothing appears
Just ran into this myself. The solution is as if-else-switch pointed out in a comment above:
// Import this
import com.facebook.react.uimanager.annotations.ReactProp;
// Not this!
import com.facebook.react.uimanager.ReactProp;
There seem to be two #ReactProp definitions in different packages and Android Studio chooses the wrong one by default.
I solved this problem using react-native 0.13.+ instead of 0.11.+

OpenCV + Android - face recognition not working

I have been implemented this project: https://github.com/yaylas/AndroidFaceRecognizer into Android Studio. I included OpenCV using tutorial: https://www.youtube.com/watch?v=OTw_GIQNbD8 (this is static initialization). Moreover, I set in Android Studio settings proper NDK location.
Problem is that, if I add this Class:
package com.yaylas.sytech.facerecognizer;
import java.util.Vector;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import android.widget.Toast;
public class DetectionBasedTracker
{
public DetectionBasedTracker(String cascadeName, int minFaceSize, boolean isFaceDetector) {
mNativeObj = nativeCreateObject(cascadeName, minFaceSize, isFaceDetector);
}
public long getNativeObj(){
return mNativeObj;
}
public void setMinFaceSize(int size) {
nativeSetFaceSize(mNativeObj, size);
}
public void detect(Mat imageGray, MatOfRect faces) {
nativeDetect(mNativeObj, imageGray.getNativeObjAddr(), faces.getNativeObjAddr());
}
public void release() {
nativeDestroyObject(mNativeObj);
mNativeObj = 0;
}
public static Vector<Mat> imageVector = new Vector<Mat>();
public static void addElement(Mat m){
imageVector.add(m);
System.out.println("--------------------------------- elementAdded: "+imageVector.size());
}
public static long getElementAt(int index){
if(index >= imageVector.size() || index < 0){
return 0;
}
System.out.println("-------------------------***** get element: "+imageVector.size()+" index: "+index);
return imageVector.elementAt(index).getNativeObjAddr();
}
public static int getImageCount(){
return imageVector.size();
}
private long mNativeObj = 0;
private static native long nativeCreateObject(String cascadeName, int minFaceSize, boolean faceDetection);
private static native void nativeDestroyObject(long thiz);
private static native void nativeStart(long thiz);
private static native void nativeStop(long thiz);
private static native void nativeSetFaceSize(long thiz, int size);
private static native void nativeDetect(long thiz, long inputImage, long faces);
}
An error is returned:
Cannot resolve corresponding JNI function
I tried everything, but the error still is there. I would like to ask, where can be a problem?
There are several reasons why the runtime might not be able to resolve the JNI function. Test these hypotheses:
The native code library didn't get bundled into your APK. Look inside the APK for it.
The native code library is in the wrong directory of the APK. Again, look and see.
The Java class got mangled by ProGuard so the names no longer match with the native library. Try turning off ProGuard. It should be off for debug builds.
If your native code library is compiled for ARM but you're running in an x86 based Android emulator (or vice versa), it won't be able to load that library.
Think of more hypotheses, then test them.
The page http://opencv.org/platforms/android.html has lots of info about OpenCV on Android, including links to tutorials.

Android-NDK: create GUI elements out of native code

as far as I understood the Android-NDK-thingy it works as follows: I have to use a NativeActivity that itself calls into the attached native code handing over some OpenGL graphics context. This context can be used by the native part to draw some things with.
What I could not fiddle out until now: how about some GUI elements? Is there a possibility to call back from native code to Java just to create some UI-elements and perhaps to use layouts? Means is it possible to use the standard Android GUI elements also with such native code?
If yes: how can this be done? If not: what alternatives exist (except drawing everything manually)?
Thanks!
If you want to use GUI stuff on the openGL view, I think it would be better to use a normal Activity instead of a NativeActivity.
You can use the Android sample called GL2JNIActivity. Check that to import it from Eclipse.
You can declare some native functions in the JNI Library part (class JNILib in the sample). which you will call when you your GUI listeners get called. Basically it will look like that:
public class GL2JNILib {
static {
// Maybe you need to load other relevant libraries here
System.loadLibrary("gl2jni");
}
public static native void init(int width, int height);
public static native void step();
/*Add here your native functions to send to the native code*/
public static native void buttonClicked();
//... add other listeners here (i.e: screen touched, etc.)
}
Then in the Activity itself (in the sample that corresponds to the class JNIActivity), you can just load an XML GUI file as usual. When you get some input through the GUI, you can just call the native functions added in the GL2JNI class. More or less it will look like that:
public class GL2JNIActivity extends Activity {
GL2JNIView mView;
Button mButton;
#Override protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
mView = new GL2JNIView(getApplication());
setContentView(mView);
mButton = (Button)findViewById(R.id.your_button);
mButton.setOnClickListener( new Button.OnClickListener(){
#Override
public void onClick(View v) {
mView.buttonClicked();
}
});
}
/*...*/
}
Finally, you have to implement the native function in the native side:
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_buttonClicked(
JNIEnv * env, jobject obj)
{
// will be called when the button is clicked
}

.How does the Android GPS work?

I'd like to understand a bit better the way GPS works in Android and I'd like to include some traces to track it and modify its behavior. In GpsLocationProvider.java I found the methods:
private native boolean native_init();
private native void native_disable();
private native void native_cleanup();
private native boolean native_start(int positionMode, boolean singleFix, int fixInterval);
private native boolean native_stop();
private native void native_set_fix_frequency(int fixFrequency);
private native void native_delete_aiding_data(int flags);
private native void native_wait_for_event();
// returns number of SVs
// mask[0] is ephemeris mask and mask[1] is almanac mask
private native int native_read_sv_status(int[] svs, float[] snrs,
float[] elevations, float[] azimuths, int[] masks);
private native int native_read_nmea(int index, byte[] buffer, int bufferSize);
private native void native_inject_location(double latitude, double longitude, float accuracy);
// XTRA Support
private native void native_inject_time(long time, long timeReference, int uncertainty);
private native boolean native_supports_xtra();
private native boolean native_inject_xtra_data(byte[] data, int length);
// DEBUG Support
private native String native_get_internal_state();
// AGPS Support
private native void native_agps_data_conn_open(String apn);
private native void native_agps_data_conn_closed();
private native void native_agps_data_conn_failed();
private native void native_set_agps_server(int type, String hostname, int port);
// Network-initiated (NI) Support
private native void native_send_ni_response(int notificationId, int userResponse);
However, I would like to see what they do in detail. Where are they implemented? I've found the qualcomm drivers for GPS but I guess that there's a missing layer in between where the hardware issues are abstracted (HAL layer?).
I hope you are aware that these are supposed to be mapped at the JNI layer to corresponding GPS vendor APIs. You are right when you say that these are implemented as part of HAL layer. The HAL layer will be part of GPS chipset Vendor code.
Since you spoke about qualcomm, I can tell you that qualcomm has the HAL layer for sure. You can check their engine part if you have their source. But it has copyrights & hence, I cannot give you the source code which implements the native APIs.

Categories

Resources