说到scheme之前一直很少接触,基本上没有使用过,最近项目中使用到了scheme,研究了一下,scheme是下data标签的一个属性,通过scheme以及action的设置可以进行页面的跳转。
当我们通过Intent启动一个Activity的时候,一般分为显式跳转和隐式跳转,而隐式跳转我们通过setAction方法就可以实现,但有时我们需要通过设置URi的方式来进行页面的跳转,隐式启动则是不明确指定启动哪个Activity或者Service,而是通过设置Action、Data、Category,让系统来筛选出合适的目标。
例如:拨打电话:
Intent intent = new Intent(Intent.ACTION_DIAL,Uri.parse(“tel:10086”));
startActivity(intent);
系统接收到隐式启动请求后,会根据系统中各个Activity在AndroidManifest.xml文件中声明的来比较和判断是否匹配当前的Intent请求的。
一 . 现在模拟一个场景,点击首页MainActivity跳转到secondActivity,点击secondActivity跳转到MainActivity(通过uri的方式),在跳转到MainActivity的时候,通过配置scheme,来实现模拟首页按钮的点击效果,具体效果图如下:
1.首先在AndroidManifest.xml中为MainActivity配置跳转参数。
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/scheme" />
</intent-filter>
2 . String.xml文件
<string name="scheme">myscheme</string>
3.MainActivity.java
public class MainActivity extends Activity
{
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
/**
*
* <初始化组件>
* <功能详细描述>
* @see [类、类#方法、类#成员]
*/
private void initView()
{
textView = (TextView)findViewById(R.id.main_to_jump);
textView.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
// 显式跳转
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
if (null != intent)
{
handlerIntent(intent);
}
}
/**
*
* <处理uri数据,模拟点击>
* <功能详细描述>
* @param intent
* @see [类、类#方法、类#成员]
*/
private void handlerIntent(Intent intent)
{
if (null != intent && null != intent.getAction() && null != intent.getScheme() && intent.getScheme().equals(getResources().getString(R.string.scheme)))
{
Uri schemeUri = intent.getData();
String schemID = schemeUri.getAuthority();
// 模拟点击
switch (schemID)
{
case Contants.PRODUCT:
Toast.makeText(MainActivity.this, "通过scheme--点击了[" + Contants.PRODUCT + "]", Toast.LENGTH_SHORT).show();
break;
case Contants.PASSWORD:
Toast.makeText(MainActivity.this, "通过scheme--点击了[" + Contants.PASSWORD + "]", Toast.LENGTH_SHORT).show();
break;
case Contants.SHARE:
Toast.makeText(MainActivity.this, "通过scheme--点击了[" + Contants.SHARE + "]", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
}
备注:onNewIntent是在该实例已经存在的情况下,才会调用,关于这个请点击:Android:onNewIntent()触发机制及注意事项
4 . SecondActivity.java
public class SecondActivity extends Activity
{
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
initView();
}
private void initView()
{
textView = (TextView)findViewById(R.id.jump_to_main);
textView.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
Intent intent = new Intent();
intent.setAction(Contants.MAIN_ACTION);
intent.setData(Uri.parse("myscheme://share"));
startActivity(intent);
}
});
}
}
上述代码,通过uri的方式实现了页面的跳转,在AndroidManifest.xml中设置了data属性,data代表数据源,是中最复杂的标签,因为不同的Activity支持的数据来源和类型多种多样,所以需要通过详细的data标签信息来指明。
Data的语法如下:
Data的语法:
<data android:host="string"
android:mimeType="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
android:port="string"
android:scheme="string" />
Uri的格式:scheme://host:port/path or pathPrefix or pathPattern
如果scheme没有指定,那其它的属性均无效;
如果host没有指定,那么port,path,pathPrefix,pathPattern均无效;
如果在manifest里这样写:<data android:scheme="something" android:host="project.example.com" />
那么Uri uri = Uri.parse("something://project.example.com"); 才可以匹配
再如:
<data android:scheme="something" android:host="project.example.com" android:port="80"/>
等同于这样写:
<data android:scheme="something"/>
<data android:host="project.example.com"/>
<data android:port="80"/>
那么Uri uri = Uri.parse("something://project.example.com:80"); 才可以匹配
可以有多个data,只需匹配其中一个即可
<activity android:name=".MyActivityTwo" android:label="@string/activityTwo">
<intent-filter>
<action android:name="android.intent.action.leo"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<data android:scheme="x-id"/>
<data android:scheme="something"/>
</intent-filter>
</activity>
Intent in = new Intent();
in.setAction("android.intent.action.leo");
in.addCategory(Intent.CATEGORY_DEFAULT); in.setData(Uri.parse("something:"));//或者用这个亦可in.setData(Uri.parse("x- id:"));
startActivity(in);
参考资料:
1.android 再解Intent,通过配置Action和Data跳转
2.intent-filter 之 data 「scheme, host, port, mimeType, path, pathPrefix, pathPattern」
二 . 浏览器启动APP
1.首先需要在AndroidMainifest.xml中对你要启动的那个activity进行如下设置:
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myscheme://" />
</intent-filter>
</activity>
2.浏览器打开如下html页,即可启动App。
<a href="myscheme://">打开app</a>
3.浏览器打开App时,如何获取网页带过来的数据。
<a href="myscheme://?arg0=0&arg1=1">打开app</a>
(1).假如你是通过浏览器打开这个网页的,那么获取数据的方式为:
Uri uri = getIntent().getData();
String test1= uri.getQueryParameter("arg0");
String test2= uri.getQueryParameter("arg1");
(2)如果使用webview访问该网页,获取数据的操作为:
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Uri uri=Uri.parse(url);
if(uri.getScheme().equals("myscheme")){
String arg0=uri.getQueryParameter("arg0");
String arg1=uri.getQueryParameter("arg1");
}else{
view.loadUrl(url);
}
return true;
}
});
参考资料:如何通过Html网页调用本地安卓app?