Android 一个应用程序调用另一个应用程序
实现行业应用调用我们可以Get到哪些技能?
* Activity的singleTask的启动模式
* 界面跳转的基本实现
* 前台Service的基本介绍和实现
* SharedPreference的简单用法
实现行业应用调用的目的
在XHL应用程序中去调用MPos应用程序,借助MPos的一些界面完成特殊的功能。
实现行业应用调用步骤
(1)创建名为XHL的应用程序
(2)创建名为MPos的应用程序
代码讲解
1.创建名为XHL的应用程序的界面
如下是XHL的主界面
public class MainActivity extends AppCompatActivity {
//要调用app的包名 + 类名
private static String MOSPACKAGE = "zlll.bg.com.example.cn.application";
private static String MPOSCLASSNAME = "zlll.bg.com.example.cn.application.WelcomeActivity";
private static String MPOSCLASSNAME2 = "zlll.bg.com.example.cn.application.MainActivity"
//要调用app的服务
private static String SERVICENAME = "zl.com.example.cn.myapplication.service.MainService";
//如下是本应用的包名
private static String PACKAGE = "zl.com.example.cn.myapplication";
private Button open,exit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
open = (Button) findViewById(R.id.open);
exit = (Button) findViewById(R.id.exit);
}
@Override
protected void onResume() {
super.onResume();
//这里通过判断某个服务是否正在运行来设定按钮的状态
if(Utils.isServiceWork(MainActivity.this,SERVICENAME)) {
open.setEnabled(false);
exit.setEnabled(true);
}else{
open.setEnabled(true);
exit.setEnabled(false);
}
public void btn(View view){
//首先判断调用的apk是否安装
boolean isAlive = Utils.isInstall(MainActivity.this,MOSPACKAGE);
if(isAlive){
Intent intent = new Intent(Intent.ACTION_MAIN);//设置action
intent.addCategory(Intent.CATEGORY_LAUNCHER);//设置category
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//设置singleTask启动模式
ComponentName cn = new ComponentName(MOSPACKAGE,MPOSCLASSNAME );//封装了包名 + 类名
//设置数据
intent.putExtra("package",PACKAGE);
intent.putExtra("className",CLASSNAME);
intent.putExtra("isOnLineSign", true);
intent.setComponent(cn);
startActivity(intent);
}else{
Toast.makeText(MainActivity.this, "没有找到对应的应用程序", Toast.LENGTH_SHORT).show();
}
}
public void exit(View view){
Toast.makeText(MainActivity.this, "退出调用的的应用程序", Toast.LENGTH_SHORT).show();
Intent intent = new Intent("com.bocs.mpos.home");//设置action
intent.putExtra("isExit", true); //设置数据
intent.setClassName(MOSPACKAGE, MPOSCLASSNAME2);//内部调用了ComponentName组件
startActivity(intent);
}
}
如下是工具类
public class Utils {
/**根据包名判断某个应用程序是否安装方法*/
public static boolean isInstall(Context context , String packageName) {
if (packageName == null || "".equals(packageName))
return false;
try {
ApplicationInfo info = context.getPackageManager().getApplicationInfo(
packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
return true;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
/**判断某个进程是否正在运行的方法*/
public static boolean isProcessWork(Context context,String runningPackage) {
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> listOfProcesses = mActivityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo process : listOfProcesses) {
if (process.processName.contains(runningPackage)) {
return true;
}
}
return false;
}
/** 判断某个服务是否正在运行的方法*/
public static boolean isServiceWork(Context mContext, String serviceName) {
boolean isWork = false;
ActivityManager myAM = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> myList = myAM.getRunningServices(40);
if (myList.size() <= 0) {
return false;
}
for (int i = 0; i < myList.size(); i++) {
String mName = myList.get(i).service.getClassName().toString();
if (mName.equals(serviceName)) {
isWork = true;
break;
}
}
return isWork;
}
}
如下是在AnroidManifest.xml中配置
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="zl.com.example.cn.myapplication" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="XHL"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:launchMode="singleTask"//以singleTask模式启动
android:label="XHL" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
如下是的界面代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试打开另一个app "
android:onClick="open" />
<Button
android:id="@+id/exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="让另一个的app退出"
android:onClick="exit" />
</LinearLayout>
如下图
2.创建名为MPos的应用程序
首先建立一个全局的集合用于管理Activity的ExitApplication,记得在AndroidManifest.xml中配置
public class ExitApplication extends Application {
private static List<Activity> activityList = new ArrayList<Activity>();
public static void remove(Activity activity) {
activityList.remove(activity);
}
public static void add(Activity activity) {
activityList.add(activity);
}
//销毁掉所有的activity
public static void exitApplication() {
for (Activity activity : activityList) {
activity.finish();
}
android.os.Process.killProcess(android.os.Process.myPid());//直接杀掉当前应用进程
}
创建一个可以管理所有Activity的基类 – BaseActivity
public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ExitApplication.add(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
ExitApplication.remove(this);
}
}
接下来写界面代码 – WelcomeActivity
public class WelcomeActivity extends BaseActivity {
//定义SP引用,用于简单地保存数据
private SharedPreferences userHis;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
userHis = getSharedPreferences("user_histroy", 0);
}
@Override
protected void onResume() {
super.onResume();
//行业应用调用时,参数是不为空的
if (getIntent() != null) {
SharedPreferences.Editor editor = userHis.edit();
if (!isEmpty(getIntent().getStringExtra("package"))) {
editor.putString("package", getIntent().getStringExtra("package"));
}
if (!isEmpty(getIntent().getStringExtra("className"))) {
editor.putString("className", getIntent().getStringExtra("className"));
}
editor.putBoolean("isOnLineSign", getIntent().getBooleanExtra("isOnLineSign", false));//在线签到的标志
editor.commit();
}
//模拟耗时操作
new Thread(){
@Override
public void run() {
try {
Thread.sleep(1000);
//启动Activity
Intent intent = new Intent(WelcomeActivity.this,MainActivity.class);
startActivity(intent);
//启动服务
Intent serviceIntent = new Intent(WelcomeActivity.this, MainService.class);
startService(serviceIntent);
finish();//当前界面finish
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
//判空方法
public static boolean isEmpty(String content) {
return content == null || "".equals(content) || "null".equals(content);
}
}
接下来写界面代码 – MainActivity
public class MainActivity extends BaseActivity {
SharedPreferences userHis;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userHis = getSharedPreferences("user_histroy", 0);
}
@Override
protected void onResume() {
super.onResume();
//如果标志位是true,那么退出应用程序,调回到行业应用
if (getIntent().getBooleanExtra("isExit",false)) {
if (!isEmpty(userHis.getString("package", ""))) {
Intent intent = new Intent();
//通过ConponentName调回到指定的界面
ComponentName cn = new ComponentName("zl.com.example.cn.myapplication",
"zl.com.example.cn.myapplication.MainActivity");
intent.setComponent(cn);
startActivity(intent);
userHis.edit().remove("package").commit();
userHis.edit().remove("className").commit();
userHis.edit().remove("isExit").commit();
//退出服务
Intent updateIntent = new Intent(MainActivity.this, MainService.class);
stopService(updateIntent);
//退出程序
ExitApplication.exitApplication();
}
}
//如果标志位是true,返回到行业应用
if (userHis.getBoolean("isOnLineSign", false)) {
Toast.makeText(MainActivity.this, "返回XHL", Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putBoolean("login_exit", true);
intent.putExtras(bundle);
ComponentName cn = new ComponentName("zl.com.example.cn.myapplication",
"zl.com.example.cn.myapplication.MainActivity");
intent.setComponent(cn);
startActivity(intent);
//移除这个标志,为了点击MPos的图标不调回到XHL中
userHis.edit().remove("isOnLineSign").commit();
}
}
public static boolean isEmpty(String content) {
return content == null || "".equals(content) || "null".equals(content);
}
}
如下是在AnroidManifest.xml中配置
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="zlll.bg.com.example.cn.application" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="mpos"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="mpos" >
<intent-filter>
<!-- 为了和XHL中退出的action一致-->
<action android:name="com.bocs.mpos.home"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity
android:name=".WelcomeActivity"
android:label="mpos" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 注册Service-->
<service android:name=".service.MainService"></service>
</application>
</manifest>
MainService的代码如下
public class MainService extends Service{
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//这里只是简单的定义了一个通知,开启前台Service
startForeground(startId,new Notification());
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
stopForeground(true);//关闭前台服务
}
如下图
跑起来的效果图如下:
总结:
Activity的singleTask的启动模式
standard:标准模式
举个例子:
现在栈的情况为:A B C D ,在D这个Activity中通过Intent跳转到D,那么栈的情况为:A B C D D
描述:每次启动一个activity,都会创建一个实例。
singleTask:栈内复用模式
举个例子:
描述:首先在栈内中去寻找这个activity,如果找到了,就去调用这个界面,不需要重新实例化。
两种设置Activity的启动模式:
(1) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); – 代码中
(2) android:launchMode=”singleTask” – AndroidManifest的Activity中
APP间界面交互的基本实现
在Android中如果要详细的描述一个组件我们需要知道该组件的所在的应用包名和类名
,我们可以使用ComponentName来封装一个组件的应用包名和组件的类名。
常见的用法:
Intent intent = new Intent();
intent .setComponent(new ComponentName(String packageName,String activityName));
startActivity(intent );
前台Service的基本介绍和实现
如果你希望Service可以一直保持运行状态,而不会由于系统内存不足的原因导致被回收,考虑使用前台Service。
前台Service和普通Service最大的区别在于它会一直有一个正在运行的图标在系统的状态栏显示
只需要在onStartCommand里面调用 startForeground,然后再onDestroy里面调用stopForeground即可
SharedPreference的简单用法
SharePreferences是用来存储一些简单配置信息的一种机制,创建的存储文件保存在/data/data//shares_prefs文件夹下
插入数据 – Editor.putxxxx方法
获取数据 – Editor.getxxxx方法
删除数据 – Editor.remove方法。
清空所有数据 –Editor.clear方法