在我们日常使用Android App的时候,会经常有这样的一种情形:在一个App中触发了某种条件会打开另一个App。例如在手机QQ中给好友发送文件,就会打开文件管理器,给好友发送照片就会打开相册或者相机,然后让你选择照片抑或拍一张照片,还有就是比较令人讨厌的,点击某个图标自动跳转到应用市场,亲~安装我们的应用吧!!!这样的情形还有很多,不胜枚举,所以作为Android开发者的我们,应该知道它的实现原理。这篇文章算是一个备忘吧,总结一下我们作为开发者接触的比较多的情形。好了,废话不多说,我们直接上代码。
1.打开第三方应用,由于博主比较喜欢泡知乎,所以接下来的例子就用知乎手机客户端作为例子吧。照例,打开我们的Android Studio,新建一个叫做TestDemo的Project,然后一直next下去即可。我们的业务逻辑大概是点击一个Button,监听器坚挺Button,如果被点击了,那么打开第三方App。
布局界面代码(其实很简单辣,就是一个按钮):
1. <RelativeLayout
2. xmlns:android="http://schemas.android.com/apk/res/android"
3. xmlns:tools="http://schemas.android.com/tools"
4. android:layout_width="match_parent"
5. android:layout_height="match_parent"
6. android:paddingLeft="@dimen/activity_horizontal_margin"
7. android:paddingRight="@dimen/activity_horizontal_margin"
8. android:paddingTop="@dimen/activity_vertical_margin"
9. android:paddingBottom="@dimen/activity_vertical_margin"
10. tools:context=".MainActivity">
11.
12. <Button
13. android:layout_marginTop="55dp"
14. android:textSize="25sp"
15. android:id="@+id/button"
16. android:text="install another App"
17. android:layout_width="match_parent"
18. android:layout_height="wrap_content" />
19.
20. </RelativeLayout>
界面效果(机器为Nexus 6):
Main_Activity.java代码:
1. package com.example.chad.testdemo;
2.
3. import android.app.SearchManager;
4. import android.content.ActivityNotFoundException;
5. import android.content.Context;
6. import android.content.Intent;
7. import android.content.pm.PackageManager;
8. import android.net.Uri;
9. import android.os.Bundle;
10. import android.support.v7.app.ActionBarActivity;
11. import android.view.Menu;
12. import android.view.MenuItem;
13. import android.view.View;
14. import android.widget.Button;
15.
16.
17. public class MainActivity extends ActionBarActivity {
18. private Button mButton;
19.
20. public static final String ANOTHER_PACKAGE_NAME = "com.zhihu.android";
21. /*
22. **启动第三方App
23. */
24. public static void launchAnotherApp(Context context){
25. if(isAppInstalled(context, ANOTHER_PACKAGE_NAME)){
26. context.startActivity(context.getPackageManager().getLaunchIntentForPackage(ANOTHER_PACKAGE_NAME));
27. else{
28. goToMarket(context, ANOTHER_PACKAGE_NAME);
29. }
30. }
31. /*
32. **检测第三方App是否已安装
33. */
34. public static boolean isAppInstalled(Context context, String packageName){
35. try {
36. 0);
37. return true;
38. catch (PackageManager.NameNotFoundException e) {
39. e.printStackTrace();
40. return false;
41. }
42.
43. }
44. /*
45. **去应用市场下载页面
46. */
47. public static void goToMarket(Context context, String packageName){
48. "market://details?id=" + packageName);
49. new Intent(Intent.ACTION_VIEW,uri);
50. try {
51. context.startActivity(goToMarket);
52. catch (ActivityNotFoundException e){
53. e.printStackTrace();
54. }
55. }
56.
57.
58. @Override
59. protected void onCreate(Bundle savedInstanceState) {
60. super.onCreate(savedInstanceState);
61. setContentView(R.layout.activity_main);
62. mButton = (Button)findViewById(R.id.button);
63. new View.OnClickListener() {
64. @Override
65. public void onClick(View v) {
66. this);
67.
68. }
69. });
70. }
71.
72.
73. @Override
74. public boolean onCreateOptionsMenu(Menu menu) {
75. // Inflate the menu; this adds items to the action bar if it is present.
76. getMenuInflater().inflate(R.menu.menu_main, menu);
77. return true;
78. }
79.
80. @Override
81. public boolean onOptionsItemSelected(MenuItem item) {
82. // Handle action bar item clicks here. The action bar will
83. // automatically handle clicks on the Home/Up button, so long
84. // as you specify a parent activity in AndroidManifest.xml.
85. int id = item.getItemId();
86.
87. //noinspection SimplifiableIfStatement
88. if (id == R.id.action_settings) {
89. return true;
90. }
91.
92. return super.onOptionsItemSelected(item);
93. }
94. }
好了,现在解释一下这段代码。
我们能否成功的掉取出指定的第三方应用的核心就是,一个正确的包名。这里解释一下什么叫包名,我们看一下MainActivity.java的第一行:
1. package com.example.chad.testdemo;
相信学过java的朋友对包一定不会陌生。就是为了唯一标识每个类并分组,所以java使用了package的概念。一般而言,包的名字都是公司网址的倒序,如com.google.*,如果对包的概念仍有疑问的同学,你可以自己找一本书翻翻,理解起来并不难。而在我们的Android开发中Package的作用是差不多的,你可以把包理解为我们每一个App的”身份证号“,它唯一标识了我们的App跟其他的App是不同的,这样才能在应用市场浩如烟海的App中确定你是唯一的,所以劝各位一定要给自己的App取一个独特的包名,要不然就会很尴尬,比如豌豆荚有一个洗白白的功能,不知道大家知不知道,如果你和别人的App包名相同,那么你的App就用可能被洗掉,被认为是一个脏应用。
实现这个功能我们定义了三个函数launchAnotherApp是功能的主体,isAppInstalled方法和goToMarket方法是被它调用来辅助它的。isAppInstalled的作用是判断这个应用是否已经被安装了,如果安装了那么好直接打开即可,如果是没有安装,那么就调用goToMarket方法进入应用市场界面,引导你下载这个App,思路还是很清晰的。
2.跳转到指定的网页
1. //浏览网页
2. public static void browesTheWeb(Context context, String theURL){ //theURL就是你指定的要打开的网页
3. Uri uri = Uri.parse(theURL);
4. new Intent(Intent.ACTION_VIEW, uri);
5. context.startActivity(i);
6. }
我们可以再监听器的onClick方法中调用这个静态方法,如下:
1. mButton.setOnClickListener(new View.OnClickListener() {
2. @Override
3. public void onClick(View v) {
4. //open the url www.baidu.com
5. //browesTheWeb(MainActivity.this, "http://www.baidu.com");
6.
7. }
8. });
3.调用系统的搜索功能
1. // search
2. public static void searchByGoogle(Context context, String contentToSearch){
3. new Intent();
4. i.setAction(Intent.ACTION_SEARCH);
5. i.putExtra(SearchManager.QUERY, contentToSearch);
6. context.startActivity(i);
7. }
我们仍然是在监听器的onClick方法中调用这个静态方法。
4.调用谷歌地图或百度地图显示位置:
1. public static void showTheMap(Context context, String mapToShow){
2. Uri uri = Uri.parse(mapToShow);
3. new Intent(Intent.ACTION_VIEW, uri);
4. context.startActivity(i);
5. }
函数调用方法(监听器部分的代码我就省略了哈):
1. showTheMap(MainActivity.this, "geo:113.461528,22.275482");
5.打电话
1. public static void callSomePhone(Context context, String PhoneNumber){
2. Uri uri = Uri.parse(PhoneNumber);
3. new Intent(Intent.ACTION_VIEW, uri);
4. context.startActivity(i);
5. }
函数调用方法:
1. callSomePhone(MainActivity.this, "tel:15958003646");
6.发短信
1. public static void sendAMessage(Context context, String PhoneNumber){
2. Uri uri = Uri.parse(PhoneNumber);
3. new Intent(Intent.ACTION_SENDTO, uri);
4. "sms_bodu", "the sms text");
5. context.startActivity(i);
6. // or the code following
7. /*Intent it = new Intent(Intent.ACTION_VIEW);
8. it.putExtra("sms_body", "TheSMS text");
9. it.setType("vnd.android-dir/mms-sms");
10. context.startActivity(it);*/
11.
12. }
函数调用方法:
1. sendAMessage(MainActivity.this, "smsto:12345678");
2.