i'am try to change brightness from my widget
with reflected method but
this code failen on moment setBacklightBrightness.invoke(power, new Object[]{Brightness});
and write invoke error.
Please help!
public static void LoadIPowerClass(Context context)
{
try{
//Load classes and objects
Object power;
Context fContext = context;
Class <?> ServiceManager = Class.forName("android.os.ServiceManager");
Class <?> Stub = Class.forName("android.os.IPowerManager$Stub");
Method getService = ServiceManager.getMethod("getService", new Class[] {String.class});
//Method asInterface = GetStub.getMethod("asInterface", new Class[] {IBinder.class});//of this class?
Method asInterface = Stub.getMethod("asInterface", new Class[] {IBinder.class}); //of this class?
IBinder iBinder = (IBinder) getService.invoke(null, new Object[] {Context.POWER_SERVICE});//
power = asInterface.invoke(null,iBinder);//or call constructor Stub?//
Method setBacklightBrightness = power.getClass().getMethod("setBacklightBrightness", new Class[]{int.class});
int Brightness = 5;
setBacklightBrightness.invoke(power, new Object[]{Brightness});//HERE Failen
Log.i(TAG, "Load internal IPower classes Ok");
}catch(InvocationTargetException e){ //HERE catch!!!!
....
Thanks you very very much for your code, it works VERY WELL !
Regarding your exception, you're probably missing the DEVICE_POWER permission in your app.
In order to get this permission, you must use a root uid. Add android:sharedUserId="android.uid.system" inside the <manifest> tag and SIGN your application using the phone's OEM key (private key used by constructor, or the private key of your development platform).
Regards
Related
I am recently try to read android source code .I have two set of source code the android-22 and the android-21. i find some differneces between these .
below is a piece of the PolicyManager's source code ,i think it is with big problem!
public class PolicyManager {
public static Window makeNewWindow(Context context) {
// this will likely crash somewhere beyond so we log it.
Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
"Call to PolicyManager.makeNewWindow is not supported", null);
return null;
}
as we can see the PolicyManager.makeNewWindow returns null directly,if i call
PolicyManager.makeNewWindow i will get a null! let's a look at Activity's attach method:
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
attachBaseContext(context);
mFragments.attachActivity(this, mContainer, null);
mWindow = PolicyManager.makeNewWindow(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
mWindow is null? mWindow.setCallback(this) will trigger a NullPointer Exception?i have to say i download the sourcecode by androidstudio ,i want to
kown is the source code wrong?
The Activity class in Android-23 Source Code
mWindow = new PhoneWindow(this)
not use PolicyManager class after api-22 to new PhoneWindow object.
when you develope under android api-23, you might create a PhoneWindow object through reflection. Here is code.
String phone_window_calss = "com.android.internal.policy.PhoneWindow";
Class phoneWindowClass = null;
try {
phoneWindowClass = Class.forName(phone_window_calss);
Constructor constructor = phoneWindowClass.getDeclaredConstructor(new Class[]{Context.class});
mWindow = (Window) constructor.newInstance(context);
} catch (Exception e) {}
After three days trying to find this over this website and others, I really need your help.
I want to test a method in a class. This method uses the activity class context to call an intent.
When I call it from the test method i get a NullPointerException.
How can i do this? (add example code please).
Accesories is the ActivityClass.
The Method in the Docking class:
public boolean powerConnected() {
boolean res = false;
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Context cont = Accessories.context;
Intent intent = cont.registerReceiver(null, filter); --Throws the exception
int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
if(plugged == BatteryManager.BATTERY_PLUGGED_AC){
Log.d(TAG, "AC "+plugged);
res = true;
}else if (plugged == BatteryManager.BATTERY_PLUGGED_USB){
Log.d(TAG, "USB "+plugged);
res = false;
}
return res;
}
The testing Method:
#Test
public void testPowerConnected_AssertParamConnected_ReturnTrue() {
Docking docking = new Docking();
boolean result = docking.powerConnected();
assertTrue(result);
}
Thank you so much.
You could refractor your code to give the context as a parameter to your method:
public boolean powerConnected(Context cont) {
....
}
so that when you call it with your test, you can use a MockContext
class CustomMock extends MockContext {
Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
// You can return a MockIntent based on your testing needs.
}
}
#Test
public void testPowerConnected_AssertParamConnected_ReturnTrue() {
Docking docking = new Docking();
MockContext cont = new CustomMock ();
boolean result = docking.powerConnected(cont);
assertTrue(result);
}
Just found the solution.
If the TestClass extends AndroidTestCase and not ActivityInstrumentationTestCase2 as I had,
there is a protected mContext in the AndroidTestCase that stores the context as a field.
After that, the only I have to do is pass this context to my method to test.
so the final code will be just this:
#Test
public void testPowerConnected_AssertParamA1Connected_ReturnTrue() {
Docking docking = new Docking();
//MockContext context = new CustomMock();
boolean result = docking.powerConnected(mContext);
assertTrue("Expected true and get "+result,result);
}
Have you considered making the powerConnected() function static? Then there would be no need for the
Docking docking = new Docking()
which I imagine is causing your problems....if it isn't then I recommend posting the LogCat output.
If Docking is a subclass of Activity, you cannot do this:
Docking docking = new Docking();
Only the Android framework can instantiate Android components (Activity, Service, BroadcastReceiver, ContentProvider), because it doesn't just call the constructors, it also sets up the appropriate Context.
You can only test a method of the activity, if it is being called within the context of that activity. This means that you need to actually have Android create the activity first and then you can test methods within that activity.
Your other option is to change the method so that it uses the Application context using getApplicationContext() instead of the activity context. In that case you wouldn't have to create an instance of the activity just to call this method.
I need to connect defined BT device by simple pressing the button.
The requirement is user shouldn't receive any notification dialogs as in case of using standard socket methods.
In my project I used this solution.
Code was next:
/**
* Return system service to work with A2DP
*
* #return bluetooth interface
*/
private static IBluetoothA2dp getIBluetoothA2dp() {
IBluetoothA2dp ibta = null;
try {
final Class serviceManager = Class.forName("android.os.ServiceManager");
final Method getService = serviceManager.getDeclaredMethod("getService", String.class);
final IBinder iBinder = (IBinder) getService.invoke(null, "bluetooth_a2dp");
final Class iBluetoothA2dp = Class.forName("android.bluetooth.IBluetoothA2dp");
final Class[] declaredClasses = iBluetoothA2dp.getDeclaredClasses();
final Class c = declaredClasses[0];
final Method asInterface = c.getDeclaredMethod("asInterface", IBinder.class);
asInterface.setAccessible(true);
ibta = (IBluetoothA2dp) asInterface.invoke(null, iBinder);
} catch (final Exception e) {
Log.e("Error " + e.getMessage());
}
return ibta;
}
It worked well until I've launched my app on Android 4.2. Now I'm unable to get IBluetoothA2dp interface because getService() method doesn't return me an IBinder with "bluetooth_a2dp" key.
Can someone help me?
Thanks in advance!
Finally got this working on 4.2. See the details here: http://code.google.com/p/a2dp-connect2/
It is quite different from 4.1 and before.
First call connect to the interface like this:
public static void getIBluetoothA2dp(Context context) {
Intent i = new Intent(IBluetoothA2dp.class.getName());
if (context.bindService(i, mConnection, Context.BIND_AUTO_CREATE)) {
} else {
// Log.e(TAG, "Could not bind to Bluetooth A2DP Service");
}
}
When the interface is returned it will call back to this:
public static ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
ibta2 = IBluetoothA2dp.Stub.asInterface(service);
}
#Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
};
ibta2 above is the IBluetoothA2dp interface.
On a related note, IBluetooth interface also changed. I use this to get the device alias name (the one the user can edit). This getRemoteAlias() function needed the mac address before. Now it takes a BluetoothDevice.
Keep in mind using these hidden interfaces is risky as they can and too often do change with new Android versions. I have been bit by that several times now. You really need to stay on top of it.
If some one needs the answer to something related to autopairing, can check my answer here.
https://stackoverflow.com/a/30362554/3920157
I am writing an android Junit test for a class that relies on extras passed to it through an Intent. I was able to get the class working properly, but I would still like to know how to write a unit test for such a class, as the test still fails.
public class AddClassEvent extends Activity{
private String eventType;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
final String cNo = extras.getString("CourseNum");
// create a model instance
final StudentDBModel model = new StudentDBModel(this);
setContentView(R.layout.add_class_event);
.....
.....
}
}
The test class looks like...
public class AddClassEventTest extends ActivityInstrumentationTestCase2<AddClassEvent>{
private StudentDBModel model = null;
private RenamingDelegatingContext context = null;
public AddClassEventTest() {
super("com.UI", AddClassEvent.class);
}
/**
* This method is called before each test.
*/
#Override
public void setUp() {
context = new RenamingDelegatingContext(getActivity(), "test_");
model = new StudentDBModel(context);
}
/*
* This function will test addNewClassEvent() from StudentDBModel
*/
public void testAddNewClassEvent(){
ContentValues courseValues = new ContentValues();
courseValues.put("CourseId", "60-415");
courseValues.put("CourseName", "Advanced Database Design");
courseValues.put("Section", "1");
courseValues.put("Location", "Erie");
courseValues.put("Credit", "3");
courseValues.put("ProfEmail", "rfortier#uwindsor.ca");
courseValues.put("Website", "cs.uwindsor.ca");
model.addNewCourses(courseValues);
int numEventsBefore = model.getNumClassEvents();
ContentValues values = new ContentValues();
values.put("EventName", "Assignment 1");
values.put("CourseId", "60-415");
values.put("EventType", "Assignment");
values.put("EventWeight", "8");
values.put("DueDate", "10/20/2010");
model.addNewClassEvent(values);
int numEventsAfter = model.getNumClassEvents();
assertEquals(numEventsBefore + 1, numEventsAfter);
}
}
The problem is, the extra that I am passing to the class AddClassEvent is a PK for my DB that is created in another class and passed to AddClassEvent through an Intent. Whenever I run the test I get a NULL Pointer Exception on the on the line:
final String cNo = extras.getString("CourseNum");
How do I create the info from the extra in the Junit Test? Is there a way to get this test to work? I have searched extensively and can't find an answer. Is there some way to falsely create the extras in the Junit test so that it thinks it is being created by the other class? If so, could someone please show me how?
OK so I have tried to take your advice and I have changed my setUp function to:
#Override
public void setUp() {
context = new RenamingDelegatingContext(getActivity(), "test_");
model = new StudentDBModel(context);
Intent addEvent = new Intent();
addEvent.setClassName("com.UI", "com.UI.AddClassEvent");
addEvent.putExtra("CourseNum", "60-415");
setActivityIntent(addEvent);
getActivity();
}
but I am still getting a NULL Pointer exception. Is my syntax wrong? Any suggestions?
The class you inherit, ActivityInstrumentationTestCase2, allows you to mock Intents. From the documentation:
You can inject custom Intents into your Activity (see setActivityIntent(Intent)).
The documentation for setActivityIntent() further clarifies:
Call this method before the first call
to getActivity() to inject a
customized Intent into the Activity
under test.
If you do not call this, the default
intent will be provided. If you call
this after your Activity has been
started, it will have no effect.
So you should be able to place a call to this method inside your setUp() before your call to getActivity(). You can pass in a mocked Intent into setActivityIntent like you mentioned -- just build a fake Intent with extras that you'd expect the Activity to see.
OK, I figured out my mistake! The code for setUp was just in the wrong order. It should look like:
#Override
public void setUp() {
Intent addEvent = new Intent();
addEvent.setClassName("com.UI", "com.UI.AddClassEvent");
addEvent.putExtra("CourseNum", "60-415");
setActivityIntent(addEvent);
context = new RenamingDelegatingContext(getActivity(), "test_");
model = new StudentDBModel(context);
}
I was calling getActivity() twice and the first call was ahead of the Intent. By using the correct order, the test runs fine. Thanks for the help McStretch.
I am using AIDL to pass objects from an Activity to a Service and am getting some strange behavior. To my understanding, the idea behind AIDL is to create an interface in a .aidl file, which android will then implement (partially) in a dynamically generated class. Android will create an abstract class called Stub, which you then need to instantiate and add the implementation of the methods which you defined in your .aidl interface. Once all of that is in place, the remote service can be instantiated, and the methods declared in the .aidl interface file (and defined in your instantiation of the Stub class) can be called.
That is my impression of how this mechanism works, however when I tried implementing it, I notice that the definitions for the methods I declared in the Stub class are not being run; instead what is being run is IBinder.transct()
Here is a snippet of what I'm trying to do:
This is implemented in my Service:
public final INetService.Stub mBinder = new INetService.Stub() {
public void sendInteger(String ID, int data) throws RemoteException {
// TODO Auto-generated method stub
}
public void sendString(String ID, String data) throws RemoteException {
ServiceConnectionHandler connHandler = new ServiceConnectionHandler(ID, data);
}
public void sendObject(String ID, NetMessage data) throws RemoteException {
ServiceConnectionHandler connHandler = new ServiceConnectionHandler(ID, data.getData());
}
};
And this is inside my Activity, which tries to use and talk to the service:
private INetService mService = null;
private NetServiceConnection conn = null;
class NetServiceConnection implements ServiceConnection
{
public void onServiceConnected(ComponentName name, IBinder service) {
mService = INetService.Stub.asInterface(service);
Log.d( "ADDERSERVICECLIENT","onServiceConnected" );
}
#Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
Log.d( "ADDERSERVICECLIENT","onServiceDisconnected" );
}
};
private void initService()
{
conn = new NetServiceConnection();
Intent i = new Intent();
i.setClassName( "framework.network", "framework.network.NetService" );
if (!bindService( i, conn, Context.BIND_AUTO_CREATE))
{
Toast.makeText(this, "bindService fails..", Toast.LENGTH_LONG).show();
}
}
....
mService.sendString((char)0, finalMessage);
The methods defined in INetService.Stub, like sendString, appear never to be called; clearly I'm missing something; any thoughts?
Thanks a lot!
Iva
Without the rest of your code, it is difficult to answer your question. See here and here for a pair of sample projects implementing a remote service and its client, using AIDL. Perhaps those implementations will give you some idea of where things are going wrong for you.
You must specify your class in an .aidl-file to make it public to IPC.
See http://fauxgrammer.com/?p=4 for more information.
Cheers!
I came across the same situation earlier today. In my case, I had two copies of the AIDL file in the client side and server side.
I was updating the AIDL file in on the client side, but totally forgot about updating the server-side AIDL. Since there's no type checking on Stub implementation it just ran but never returned anything.