package com.wuba.activity.base;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.wuba.R;
import com.wuba.activity.main.MainActivity;
import com.wuba.common.Constant;
public class MenuAndTabActivity extends MenuActivity{
protected LinearLayout FastTabMainLinearLayout;
private RelativeLayout RelativeLayoutTab00;
private RelativeLayout RelativeLayoutTab01;
private RelativeLayout RelativeLayoutTab02;
private RelativeLayout RelativeLayoutTab03;
private RelativeLayout RelativeLayoutTab04;
private boolean isadded = false;
private View view;
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
}
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
showFakeTitleBar();
return super.onMenuOpened(featureId, menu);
}
@Override
public void onOptionsMenuClosed(Menu menu) {
hideFakeTitleBar();
super.onOptionsMenuClosed(menu);
}
@Override
public void onStart() {
super.onStart();
view = getLayoutInflater().inflate(R.layout.fast_tab, null);
MenuAndTabListener mtListener = new MenuAndTabListener();
FastTabMainLinearLayout = (LinearLayout) view.findViewById(R.id.FastTabMainLinearLayout);
RelativeLayoutTab00 = (RelativeLayout) view.findViewById(R.id.RelativeLayoutTab00);
RelativeLayoutTab00.setTag(Integer.parseInt("0"));
RelativeLayoutTab00.setOnClickListener(mtListener);
RelativeLayoutTab01 = (RelativeLayout)view. findViewById(R.id.RelativeLayoutTab01);
RelativeLayoutTab01.setTag(Integer.parseInt("1"));
RelativeLayoutTab01.setOnClickListener(mtListener);
RelativeLayoutTab02 = (RelativeLayout) view.findViewById(R.id.RelativeLayoutTab02);
RelativeLayoutTab02.setTag(Integer.parseInt("2"));
RelativeLayoutTab02.setOnClickListener(mtListener);
RelativeLayoutTab03 = (RelativeLayout) view.findViewById(R.id.RelativeLayoutTab03);
RelativeLayoutTab03.setTag(Integer.parseInt("3"));
RelativeLayoutTab03.setOnClickListener(mtListener);
RelativeLayoutTab04 = (RelativeLayout) view.findViewById(R.id.RelativeLayoutTab04);
RelativeLayoutTab04.setTag(Integer.parseInt("4"));
RelativeLayoutTab04.setOnClickListener(mtListener);
}
private class MenuAndTabListener implements android.view.View.OnClickListener {
final MenuAndTabActivity mtActivity;
public void onClick(View view) {
Intent intent = new Intent();
Bundle bundle = new Bundle();
switch ((Integer)view.getTag()) {
case 0:
bundle.putString(Constant.TABINDEX, "0");
MainActivity.CURRENT_TAB = 0;
break;
case 1:
bundle.putString(Constant.TABINDEX, "1");
MainActivity.CURRENT_TAB = 1;
break;
case 2:
bundle.putString(Constant.TABINDEX, "2");
MainActivity.CURRENT_TAB = 2;
break;
case 3:
bundle.putString(Constant.TABINDEX, "3");
MainActivity.CURRENT_TAB = 3;
break;
case 4:
bundle.putString(Constant.TABINDEX, "4");
MainActivity.CURRENT_TAB = 4;
break;
default:
break;
}
intent.putExtras(bundle);
intent.setClass(MenuAndTabActivity.this, MainActivity.class);
MenuAndTabActivity.this.startActivity(intent);
}
MenuAndTabListener() {
super();
mtActivity = MenuAndTabActivity.this;
}
}
private void hideFakeTitleBar(){
android.view.WindowManager.LayoutParams layoutparams = new android.view.WindowManager.LayoutParams(
-1,
-1,
WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE ,
-1);
layoutparams.gravity = 48;
layoutparams.y = 25;
WindowManager windowmanager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
View view1 = view;
windowmanager.updateViewLayout(view1, layoutparams);
View view2 = view;
windowmanager.removeView(view2);
isadded = false;
}
private void showFakeTitleBar(){
//让一个视图浮动在你的应用程序之上
View view1 = getWindow().peekDecorView();
WindowManager windowmanager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
android.view.WindowManager.LayoutParams layoutparams = new android.view.WindowManager.LayoutParams(
200,//浮动的大小 宽
300, //浮动的 高
WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE ,
-1);
layoutparams.gravity = 48;
Rect rect = new Rect();
view1.getWindowVisibleDisplayFrame(rect);
int i = rect.top;
layoutparams.y = i;
try
{
if (isadded)
{
windowmanager.removeView(view);
}
}
catch (Exception e)
{
//
}
windowmanager.addView(view, layoutparams);
isadded = true;
}
}
在 Android的 Settings->Sound and Display中有 Orientation这一设置项。当选中时,反转手机,手机屏幕会随之旋转,一般只可以旋转 90度。
这一 settings设置是在文件 SoundAndDisplaySettings.java中,该项对应的键字符串为:
其默认值保存在 xml文件中,默认是 Enable。 UI程序初始化时会根据其值是否在复选框中打勾(代码在 onCreate函数中):
当用户改变了该值时,会保存起来:
文件 frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindowManager.java中的 SettingsServer会随时监控其值,对用户设置做出反应:
上述是设置生效流程。当 Orientation设置 Enable时,会发生什么呢?
在 PhoneWindowManager.java有个 Listener,它会根据 Sensor判别出的旋转方向,调用 WindowManager.setRotation让屏幕进行旋转。另外,当应用程序显示禁止屏幕旋转时则不会旋转,见函数 needSensorRunningLp()。
在 WindowOrientationListener(见文件 javaframeworks/base/core/java/android/view/WindowOrientationListener.java)中会监听 Sensor的值,对旋转方向进行判断,然后调用抽象方法 onOrientationChanged,因此,只要在子类 Listener中重新实现这个函数即可对四个不同方向做出响应(见上面让屏幕旋转即是一例)。
遗憾的是在 Donut和 Éclair中,对旋转方向的识别只给出了 90度旋转,在 Froyo中增加了一个 270度旋转,不支持 180度即倒立的操作。
可以在修改下面代码,判断来自于 Gsensor的值,识别出旋转方向:
在Froyo中,对上述算法进行了修改,让其报出270度的旋转方向。
修改下面函数 void android.view.WindowOrientationListener .SensorEventListenerImpl .onSensorChanged(android.hardware.SensorEvent event)
float[] values = event.values;
float X = values[_DATA_X];
float Y = values[_DATA_Y];
float Z = values[_DATA_Z];
//For fixing the problem of Sensor change the window orientation error but the sensor game is no problem.
float OneEightyOverPi = 57.29577957855f;
float gravity = (float) Math.sqrt(X*X+Y*Y+Z*Z);
float zyangle = (float)Math.asin(Z/gravity)*OneEightyOverPi;
int rotation = -1;
if ((zyangle <= PIVOT_UPPER) && (zyangle >= PIVOT_LOWER)) {
// Check orientation only if the phone is flat enough
// Don't trust the angle if the magnitude is small compared to the y value
float angle = (float)Math.atan2(Y, -X) * OneEightyOverPi;
int orientation = 90 - (int)Math.round(angle);
// normalize to 0 - 359 range
while (orientation >= 360) {
orientation -= 360;
}
while (orientation < 0) {
orientation += 360;
}
Log.i("Tiger","orientation="+orientation);
//确定由角度与屏幕方向的对应范围
if(orientation > 325 || orientation <= 45){
rotation = Surface.ROTATION_0;
}else if(orientation > 45 && orientation <= 135){
rotation = Surface.ROTATION_270;
}else if(orientation > 135 && orientation < 225){
rotation = Surface.ROTATION_180;
}else {
rotation = Surface.ROTATION_90;
}
Log.i("Tiger","mSensorRotation="+mSensorRotation+" , rotation="+rotation);
if ((rotation != -1) && (rotation != mSensorRotation)) {
mSensorRotation = rotation;
onOrientationChanged(mSensorRotation);
}
}
需求:
要求让用户选择喜欢的第三方应用下载并通过自己的UI运行
关键问题:
(1) 可交互下载, 用户可取消,显示进度.................这个问题好解决,有很多方式,如果不会可以联系我
(2) 安装apk
(3) 运行安装过的应用 ...... 怎样定位应用的Activity并激活 ( 如果是自己的activity就好办了 )
(1) 安装apk
直接贴出代码就明白
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File("/sdcard/1.apk")), "application/vnd.android.package-archive");
startActivity(intent);
其中/sdcard/1.apk 就是要安装的apk,上面代码实际上是请求android的管理安装的activity
如果要强制安装过程,目前我还没有找到解决方法
(2)运行应用
首先android有一个PackageManager,这玩意功能很强大,功能就和它的意思一样
假设:如果我们知道一个第三方Application的包的名称和Activity的名称,是否可以启动它的,答案当让市YES
启动代码:
PackageManager pm;
//初始化pm, 比如在activity里可以PackageManager pm = getPackageManager();
PackageInfo pi = pm.getPackageInfo("包的名称", PackageManager.GET_ACTIVITIES);
//PackageInfo 包含丰富的包的信息,这个'包的名称'是什么,在AndroidManifest.xml中有明确定义
// 比如 package="xxx.yyy.Portal.UI"
ActivityInfo ai=pi.activities[0]; // ActivityInfo 同样道理 他是 Activity的信息
//这里指向第一个包中的Activity, 大多数都是第一个Activity为启动Activity
if(ai==null) throw new Exception(pkg+"不包含任何Activity");
String sName=ai.name; //这里就得到Activity的类名了
启动它:
Intent intent = new Intent();
intent.setComponent(new ComponentName(pkg,sName));
parent.startActivity(intent);
(3)获得第三方应用的包名
只要有包名,就可以启动Activity了,但是不知道名字怎么办?
如果应用没有安装自然启动不了,只要安装了就有办法。
方法1 :
MyBroadcastReceiver myReceiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_INSTALL);
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addDataScheme("package");
registerReceiver(myReceiver, filter);
监视安装,在MyBroadcastReceiver的onReceive函数里
public void onReceive(Context arg0, Intent intent) {
String sPackageName=intent.getDataString(); //这个就是包名
}
也可以使用 AndroidManifest.xml配置来监视
方法2 :
枚举所有安装的应用,根据你自己的条件筛选
使用PackageManager的
public abstract List<PackageInfo> getInstalledPackages (int flags) 可以获得安装应用的列表