can't import android.os.SystemProperties in Camera app - android

In camera.java, I need to get property in system. However, I can't import android.os.SystemProperties, compile camera always complains:
packages/apps/Camera/src/com/android/camera/Camera.java:53: cannot find symbol
symbol : class SystemProperties
location: package android.os
import android.os.SystemProperties;
In the beginning of camera.java, I included:
import android.os.Message;
import android.os.MessageQueue;
import android.os.SystemClock;
import android.os.SystemProperties; /* (this is in line 53)*/
It seems SystemProperties is not in android.os package, but I have checked the frameworks source code, it's indeed in it.
This happen in camera app. I found many apps under packages/app dir using SystemProperties in this manner. It's really strange.

SystemProperties class is setted 'hide' annotation.
So you want to use this class in application layer,
you have to use refelection.
the definition of SystemProperties class is below.
package android.os;
/**
* Gives access to the system properties store. The system properties
* store contains a list of string key-value pairs.
*
* {#hide}
*/
public class SystemProperties

i have encounter the same problem as you have, and i use the code below, and solve the problem by using refelection. hope it would be help
//set SystemProperties as you want
public static void setProperty(String key, String value) {
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method set = c.getMethod("set", String.class, String.class);
set.invoke(c, key, value );
} catch (Exception e) {
Log.d(LOGTAG, "setProperty====exception=");
e.printStackTrace();
}
}

Related

Example for replacement for InstrumentationRegistry.getContext()

With AndroidX the InstrumentationRegistry is now deprecated. The documentation states
This method is deprecated. In most scenarios, getApplicationContext() should be used instead of the instrumentation test context. If you do need access to the test context for to access its resources, it is recommended to use getResourcesForApplication(String) instead.
However, I cannot find any examples of how to obtain the instance of PackageManager in test to invoke getResourcesForApplication and which package name should be provided to its string parameter.
For instance, here is the code that currently works:
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.IOException;
import java.io.InputStream;
import androidx.test.InstrumentationRegistry;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import static org.junit.Assert.*;
#RunWith(AndroidJUnit4.class)
public class MyTest {
#Test
public void processImage() {
// load image from test assets
AssetManager am = InstrumentationRegistry.getContext().getAssets();
InputStream is = null;
Bitmap image = null;
try {
is = am.open("image.jpg");
image = BitmapFactory.decodeStream(is);
} catch (IOException e) {
e.printStackTrace();
} finally {
if ( is != null ) {
try {
is.close();
} catch (IOException ignored) { }
}
}
assertNotNull(image);
// do something with the image
}
}
Now, how to rewrite this test without using the deprecated InstrumentationRegistry.getContext()? Keep in mind that image.jpg is not part of the application's assets - it's located in src/androidTest/assets folder and gets packaged into AppName-buildType-androidTest.apk (it's not present in the AppName-buildType.apk, for which I know the package name).
How to deduce the package name of the test APK? Is it possible to avoid hardcoding package name strings in my unit test? I am looking for a solution that is as elegant as the original code, but does not use deprecated methods.
I think you should simply use InstrumentationRegistry.getInstrumentation().getContext().getAssets() instead of InstrumentationRegistry.getContext().getAssets().
It will use your test context, so you should get your assets.

Using native Android view in ReactNative: Constructor ReactImageView in class ReactImageView cannot be applied to given types

Attempting to create an Android view to use in ReactNative later on.
This is the code that I wrote following the official tutorial, but I'm still getting some troubles compiling.
Here is the error message that I get:
Error:(15, 53) error: constructor ReactImageView in class ReactImageView cannot be applied to given types;
required: Context,AbstractDraweeControllerBuilder,GlobalImageLoadListener,Object
found: no arguments
reason: actual and formal argument lists differ in length
Here instead is the code:
package com.androidbridge;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.views.image.ReactImageView;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.drawee.backends.pipeline.Fresco;
import javax.annotation.Nullable;
public class ReactImageManager extends SimpleViewManager<ReactImageView> {
public static final String REACT_CLASS = "RCTImageView";
private Object mCallerContext;
public ReactImageManager(Object mCallerContext) {
this.mCallerContext = mCallerContext;
}
#Override
public String getName() {
return REACT_CLASS;
}
#Override
protected ReactImageView createViewInstance(ThemedReactContext reactContext) {
return new ReactImageView(reactContext, Fresco.newDraweeControllerBuilder(), mCallerContext);
}
}
I am kind of lost as the code is derived from the official tutorial.
It seems like the signature of the class ReactImageView has changed since the tutorial was written, the constructor now also require you to pass an object of type GlobalImageLoadListener. It is marked as nullable as of the latest react-native version, so you can try just passing a null reference.
I just got started myself and find the tutorial somewhat lacking.

Cannot find android.app.ApplicationPackageManager

When compiling the following example from the robolectric migration guide
package com.jongla.soundmash.robolectric
import org.robolectric.shadows.ShadowApplicationPackageManager
import org.robolectric.annotation.Implements
import android.app.ApplicationPackageManager
#Implements(value = ApplicationPackageManager.class, inheritImplementationMethods = true)
class MyCustomPackageManager extends ShadowApplicationPackageManager {
}
AndroidStudio is giving me Unresolved reference: ApplicationPackageManager. Does anyone know what I need to do to get this example to compile? Do I need some additional testCompile package in gradle?
When I was looking through Roboloectric source code, I ve spotted attribute className to specify class name instead. And it works like magic.
#Implements(className = "android.app.ApplicationPackageManager", inheritImplementationMethods = true)
public class MyCustomPackageManager extends ShadowApplicationPackageManager {
}
Migration document is clearly incorrect, when suggesting to use value as ApplicationPackageManager class is private and not visible for user code.

Android reflection doesn't work - it don't find any class

I have an Android application.
I want to scan for all classes within a package for a specify annotation.
I have:
package com.sample.package;
import com.sample.core.Controller;
import com.sample.core.ProtocolId;
#Controller
public class OtherController implements ControllerInterface{
#ProtocolId(id=100)
public void doSomething(){
//do something
}
}
I'm finding for classes annotated with #Controller for a specify #ProtocolId number.
I'm using Google Reflections library.
Here is how I'm scanning:
package com.sample.package;
import org.reflections.ReflectionUtils;
import org.reflections.Reflections;
import com.sample.core.Controller;
import com.sample.core.ProtocolId;
public class FrontController {
public void executeProperControllerMethodBasedOnId(){
Reflections ref = new Reflections("com.sample.package");
Set<Class<?>> classes = ref.getTypesAnnotatedWith(Controller.class);
System.out.println(classes.size()); //THE SIZE IS 0!!!
//The reflection doesn't worked! It didn't found any class!
}
}
The above code doesn't find any class annotated with specify annotation. Is
there something which I miss when I'm using google reflection library on
android?

How to access jar file from Unity with different bundle identifier in Unity & package name in Java?

I have created a plugin for unity in java jar.
In Java, my package name is com.android.test.
In Unity, my Bundle Identifier is com.android.test. This is working fine with the code below.
But if I change my Bundle Identifier to com.android.test2 in Unity, the code below throws an exception Class not Found: com.android.test2.myplugin.
Is there any way to access a jar file whose package name is different from Unity Bundle Identifier name?
Here is my unity C# code to access Jar:
static IntPtr cls_Activity;
static IntPtr fid_Activity;
static IntPtr obj_Activity;
static IntPtr cls_OurAppNameActivityClass;
static IntPtr startAdsMethod;
cls_Activity = AndroidJNI.FindClass("com/unity3d/player/UnityPlayer");
fid_Activity = AndroidJNI.GetStaticFieldID(cls_Activity, "currentActivity", "Landroid/app/Activity;");
obj_Activity = AndroidJNI.GetStaticObjectField(cls_Activity, fid_Activity);
cls_OurAppNameActivityClass = AndroidJNI.FindClass("com/android/test/myplugin");
startAdsMethod = AndroidJNI.GetMethodID(cls_OurAppNameActivityClass, "Instantiate", "()V");
if (AndroidJNI.IsInstanceOf(obj_Activity, cls_OurAppNameActivityClass) != false)
{
Debug.Log("Activity IS a OurAppNameActivity");
jvalue[] myArray = new jvalue[1];
AndroidJNI.CallVoidMethod(obj_Activity, startAdsMethod, myArray);
Debug.Log("Activity Leaving a OurAppNameActivity");
}
your package name needs to be same in both unity and in java else they cannot be accessed.
Yes you can.
Follow the below steps
1.While creating android project give a name to your MainActivity
(instead of MainActivity Let us say MYAndroidPlugin)
2.Now in MYAndroidPlugin.java you will see the class MYAndroidPlugin,Modify it as follows`
package com.mydomain.androidplugin;
import android.app.Activity;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;
public class MyAndroidPlugin {
public MyAndroidPlugin(){
//default constructor
}
public void makeToast(final String message, final int length) {
final Activity a = UnityPlayer.currentActivity;
a.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(a, message, length).show();
}
});
}
3.Export it as jar via gradle task and place jar file in you unityproject/Assets/Plugins/Android
4.in the c# script(in the toast method) directly refer your class
public void TestToast(){
using(AndroidJavaObject jo = new AndroidJavaObject("com.mydomain.androidplugin.MYAndroidPlugin"))
jo.Call ("makeToast", "my plugin worked", 2);
}
5.That's it call this method to make a toast
you can now directly refer a jar of any identifier

Categories

Resources