Android 通过不同的进程通知应用程序非activity class
Android Informing application through different process non-activity class
我目前正在开发一个需要一些 adb 命令的应用程序
首先我在应用程序 Module1 中有一个单独的模块,那里有 com.mordred.xyz.Main class
public class Main {
public static void main(String[] args) {
System.out.println("mordred main class is instantiated");
// rest of code
}
}
我正在通过 adb (adb shell dalvikvm -cp com.mordred.MyApplication com.mordred.xyz.Main
)
实例化 Main class (com.mordred.xyz.Main)
我的应用程序中有一个 MainActivity (com.mordred.MyApplication.MainActivity)
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// MainActivity rest of code
}
}
所以问题是即使应用程序已关闭,我如何通知 application.MainActivity "Main class is instantiated through adb"?
我尝试 Context.sendIntent 但它需要 Context 对象,而且我不能从 MainActivity 或其他对象传递 Context 对象(因为我希望 Main class 可以实例化,即使应用程序不是 运行)
我不想使用隐藏的 apis(IActivityManager 有 broadcastIntent 方法但是 class 是隐藏系统 api)
我能为它做什么?
更新:
尤里卡,可能我找到了办法,
我将在 Main class 中设置一个硬编码路径并在其中创建一个虚拟文件,然后通过 File.setReadable() 为所有人提供可读和可写权限,然后当 Main class 被实例化,它会在该文件中写入类似 "Main: 1" 的内容,然后我将在应用程序的 MainActivity class 中添加一个检查,它将检查该文件是否为 "Main: 1" , ("Main: 1"表示Mainclass被实例化否则"Main: 0"表示反之)
好的,我找到了一种更干净、更好的方法,是的,它的反射 hack:P
这是我在全球范围内发送 Intents 的功能,可以从任何地方调用
我对其进行了测试并且效果很好,同时请注意:它用于 >Marshmallow,(因为主要的 broadcastIntent() 方法的参数类型)
public void sendGlobalIntent(Intent intent,String[] requiredPermissions) {
try {
Class<?> cActivityManagerNative = Class
.forName("android.app.ActivityManagerNative");
Method mGetDefault = cActivityManagerNative.getMethod("getDefault");
mGetDefault.setAccessible(true);
Object oActivityManagerNative = mGetDefault.invoke(null);
Method[] methods = cActivityManagerNative.getMethods();
Method m = null;
for (Method method : methods) {
if (m.getName().equals("broadcastIntent")) {
m = method;
}
}
if (m == null) {
return;
}
m.setAccessible(true);
m.invoke(oActivityManagerNative, null, intent, null, null, 0, null,
null, requiredPermissions, -1, null, true, false, android.os.Process.myUid() / 100000);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
我目前正在开发一个需要一些 adb 命令的应用程序
首先我在应用程序 Module1 中有一个单独的模块,那里有 com.mordred.xyz.Main class
public class Main {
public static void main(String[] args) {
System.out.println("mordred main class is instantiated");
// rest of code
}
}
我正在通过 adb (adb shell dalvikvm -cp com.mordred.MyApplication com.mordred.xyz.Main
)
我的应用程序中有一个 MainActivity (com.mordred.MyApplication.MainActivity)
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// MainActivity rest of code
}
}
所以问题是即使应用程序已关闭,我如何通知 application.MainActivity "Main class is instantiated through adb"?
我尝试 Context.sendIntent 但它需要 Context 对象,而且我不能从 MainActivity 或其他对象传递 Context 对象(因为我希望 Main class 可以实例化,即使应用程序不是 运行)
我不想使用隐藏的 apis(IActivityManager 有 broadcastIntent 方法但是 class 是隐藏系统 api)
我能为它做什么?
更新:
尤里卡,可能我找到了办法,
我将在 Main class 中设置一个硬编码路径并在其中创建一个虚拟文件,然后通过 File.setReadable() 为所有人提供可读和可写权限,然后当 Main class 被实例化,它会在该文件中写入类似 "Main: 1" 的内容,然后我将在应用程序的 MainActivity class 中添加一个检查,它将检查该文件是否为 "Main: 1" , ("Main: 1"表示Mainclass被实例化否则"Main: 0"表示反之)
好的,我找到了一种更干净、更好的方法,是的,它的反射 hack:P
这是我在全球范围内发送 Intents 的功能,可以从任何地方调用
我对其进行了测试并且效果很好,同时请注意:它用于 >Marshmallow,(因为主要的 broadcastIntent() 方法的参数类型)
public void sendGlobalIntent(Intent intent,String[] requiredPermissions) {
try {
Class<?> cActivityManagerNative = Class
.forName("android.app.ActivityManagerNative");
Method mGetDefault = cActivityManagerNative.getMethod("getDefault");
mGetDefault.setAccessible(true);
Object oActivityManagerNative = mGetDefault.invoke(null);
Method[] methods = cActivityManagerNative.getMethods();
Method m = null;
for (Method method : methods) {
if (m.getName().equals("broadcastIntent")) {
m = method;
}
}
if (m == null) {
return;
}
m.setAccessible(true);
m.invoke(oActivityManagerNative, null, intent, null, null, 0, null,
null, requiredPermissions, -1, null, true, false, android.os.Process.myUid() / 100000);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}