Android 一个应用程序调用另一个应用程序

标签: android 应用程序 应用程序 | 发表时间:2016-04-26 21:36 | 作者:ZL_LZ
出处:http://blog.csdn.net

实现行业应用调用我们可以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方法

作者:ZL_LZ 发表于2016/4/26 13:36:13 原文链接
阅读:17 评论:0 查看评论

相关 [android 应用程序 应用程序] 推荐:

Android 应用程序

- - CSDN博客推荐文章
Android 应用程序由四个模块构造而成:Activity、Intent 、Content Provider 、Service. 下面简单介绍一下如下模块的含义:. 1、Activity  "活动". 一个Activity就是单独的屏幕,每一个活动都被实现为一个独立的类,并且从活动基类中继承而来,活动类将会显示由视图控件组成的用户接口并对事件作出响应.

Android 一个应用程序调用另一个应用程序

- - CSDN博客推荐文章
实现行业应用调用我们可以Get到哪些技能. * Activity的singleTask的启动模式 * 界面跳转的基本实现 * 前台Service的基本介绍和实现 * SharedPreference的简单用法. 在XHL应用程序中去调用MPos应用程序,借助MPos的一些界面完成特殊的功能. (1)创建名为XHL的应用程序.

Eclipse开发Android应用程序入门

- Bingnan - 酷壳 - CoolShell.cn
原文出处:http://www.smashingmagazine.com/2010/10/25/get-started-developing-for-android-with-eclipse/. 如今的移动设备应用程序开发充满着让人振奋的东西. 功能强大的硬件支持,平板电脑,多样的软件平台(塞班 OS,iOS,WebOS,Windows Phone 7…),移动设备开发者前景充满了机会和挑战.

android应用程序线程的监控

- - CSDN博客推荐文章
所以就开始研究起来,经过半天的模式总用有点启发,下面就简单介绍一个简单的线程监控:. DDMS是一款Google* 提供的应用,可作为独立的工具运行,也可通过ADT Eclipse* 插件集成到Eclipse* 中. 它提供了强大的特性集合,能帮助您快速了解应用的运行状况. 线程更新DDMS中的线程监控和评测浏览对于管理大量线程的应用很有用.

10款在Google labs诞生的Android应用程序

- HUan - cnBeta.COM
Google研究部门的高级副总裁Bill Coughran通过Google博客表示公司将关闭Google labs,因为Google打算集中资源开发重点项目. Google计划先结束所有实验,然后着重开发那些已成形的产品. 这并不意味着Google停止了一切创新活动,Google员工依旧会花时间进行“宠物计划”(就是工程师每周有一天时间将自己最疯狂的想法付诸实践),同时也会继续开发新产品,但是会终止所有实验室项目.

【外刊IT评论】如何发布你的Android应用程序

- 旺旺 - 外刊IT评论网
本文是从 Some Things To Know About Publishing Android Apps 这篇文章翻译而来. 到目前为止,在Android交易市场(Android Market)里,已经有我的2个应用程序了,所以,我想写出一点关于Android应用程序发布过程的东西,用来告诉那些想发布自己的应用程序的朋友们,在发布过程中会遇到哪些的事情.

Android应用程序需不需要手动退出?

- Jackie - 互联网的那点事
不止一次,也不止一个人问过这个问题. 我们不妨从了解这个系统对于应用程序管理的一些内部机制开始说明原因. 对于Android系统而言,包含“进程”和“服务”. “进程”有正在运行的,也有刚刚离开在后台缓存的. “服务”是一个无界面、长时间运行的应用功能,并且不会轻易被终止. 我们知道,在Android中可以快速通过主页键(home)或者使用返回键(←)逐步离开应用程序.

Android应用程序是否需要手动退出

- Tomy - Tech2IPO
不止一次,也不止一个人问过这个问题. 我们不妨从了解这个系统对于应用程序管理的一些内部机制开始说明原因. 对于Android系统而言,包含“进程”和“服务”. “进程”有正在运行的,也有刚刚离开在后台缓存的. “服务”是一个无界面、长时间运行的应用功能,并且不会轻易被终止. 我们知道,在Android中可以快速通过主页键(home)或者使用返回键(←)逐步离开应用程序.

Android应用程序需不需要手动退出?

- jk - 网易用户体验设计中心博客
不止一次,也不止一个人问过这个问题. 我们不妨从了解这个系统对于应用程序管理的一些内部机制开始说明原因. 对于Android系统而言,包含”进程”和”服务”. ”进程”有正在运行的,也有刚刚离开在后台缓存的. ”服务”是一个无界面、长时间运行的应用功能,并且不会轻易被终止. 我们知道,在Android中可以快速通过主页键(home)或者使用返回键(←)逐步离开应用程序.