안 드 로 이 드 360 데스크 톱 모 바 일 디 스 플레이 창 효과 모방

안녕하세요,오늘 여러분 께 360 핸드폰 위 사 부상 창 효 과 를 본 뜬 튜 토리 얼 을 가 져 왔 습 니 다.시작 하기 전에 제 가 먼저 상 관 없 는 말 을 할 수 있 도록 허락 해 주 십시오.
자신 도 모 르 게 저 는 안 드 로 이 드 를 접 한 지 3 년 이 되 었 습 니 다.그 동안 각종 성장 은 여러분 의 고수 들 의 도움 이 빠 질 수 없 었 습 니 다.항상 많은 고수 들 이 자신의 경험 을 인터넷 에 쓰 고 여러분 들 이 공부 할 수 있 도록 해 주 었 습 니 다.저도 그 중에서 많은 혜택 을 받 았 습 니 다.여기 서 깊 은 감 사 를 드 립 니 다.그러나 저 는 제 가 평소에 느 낀 것 을 여러분 과 나 누고 같이 공부 한 적 이 없다 는 것 을 알 게 되 었 습 니 다.너무 봉사 정신 이 없습니다.그래서 저 는 통 증 을 가 라 앉 히 고 오늘부터 블 로 그 를 쓰기 로 결 정 했 습 니 다.제 뒤에 있 는 개발 자 를 지적 하여 안 드 로 이 드 개발 자의 대열 에 빨리 들 어 갈 수 있 기 를 바 랍 니 다.
자,쓸데없는 말 을 이렇게 많이 하 자.다음은 오늘 의 주제 로 들 어가 자.
360 휴대 전화 위 사 는 많은 사람들 이 휴대 전화 에 이 소프트웨어 를 설치 할 것 이 라 고 믿는다.그러면 우 리 는 그것 의 데스크 톱 부상 창 효과 에 대해 낯 설 지 않 을 것 이다.다음 그림 을 보십시오.
           
먼저 작은 부상 창 은 현재 몇%의 메모 리 를 사 용 했 는 지 보 여 줍 니 다.작은 부상 창 을 클릭 하면 큰 부상 창 이 나타 나 고 한 번 의 클릭 으로 가속 할 수 있 습 니 다.자,이제 비슷 한 효 과 를 모 의 해 보 자.
기본 적 인 실현 원 리 를 말씀 드 리 겠 습 니 다.이 데스크 톱 부상 창의 효 과 는 Widget 과 유사 하지만 Widget 보다 훨씬 유연 합 니 다.주로 Window Manager 라 는 종 류 를 통 해 이 루어 집 니 다.이 종류의 addView 방법 을 사용 하여 부상 창 을 추가 합 니 다.updateViewLayout 방법 은 부상 창의 인 자 를 업데이트 하 는 데 사 용 됩 니 다.removeView 는 부상 창 을 제거 하 는 데 사 용 됩 니 다.그 중에서 부상 창의 매개 변 수 는 상세 하 게 설명 할 필요 가 있다.
Window Manager.LayoutParams 라 는 종 류 는 부상 창 에 필요 한 인 자 를 제공 하 는 데 사 용 됩 니 다.그 중에서 자주 사용 되 는 변수 가 몇 개 있 습 니 다.
type 값 은 부상 창의 종 류 를 확인 하 는 데 사 용 됩 니 다.일반적으로 2002 로 설정 되 어 있 으 며 모든 프로그램 위 에 있 지만 상태 표시 줄 아래 에 있 습 니 다.
flags 값 은 부상 창의 행동 을 확인 하 는 데 사 용 됩 니 다.예 를 들 어 초점 을 맞 출 수 없고 비 모드 대화 상자 등 속성 이 매우 많 습 니 다.문 서 를 볼 수 있 습 니 다.
gravity 값 은 부상 창의 정렬 방식 을 확정 하 는 데 사용 되 며,일반적으로 왼쪽 상단 을 정렬 하 는 것 으로 설정 되 어 있 으 며,이렇게 하면 부상 창 을 드래그 할 때 좌 표를 계산 하기에 편리 하 다.
x 값 은 부상 창의 위 치 를 확인 하 는 데 사 용 됩 니 다.부상 창 을 가로로 이동 하려 면 이 값 을 바 꿔 야 합 니 다.
y 값 은 부상 창의 위 치 를 확인 하 는 데 사 용 됩 니 다.부상 창 을 세로 로 이동 하려 면 이 값 을 바 꿔 야 합 니 다.
width 값 은 부상 창의 폭 을 지정 하 는 데 사 용 됩 니 다.
height 값 은 부상 창의 높이 를 지정 하 는 데 사 용 됩 니 다.
이 창 을 만 들 려 면 사용자 에 게 권한 을 신청 해 야 하기 때문에 AndroidManifest.xml 에 추가 해 야 합 니 다.<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />원 리 를 소 개 했 으 니 다음은 코드 로 실현 하 겠 습 니 다.우선 Eclipse 에 안 드 로 이 드 프로젝트 를 새로 만 듭 니 다.프로젝트 이름 은 360 Float Window Demo 입 니 다.그리고 레이아웃 파일 을 쓰 세 요.레이아웃 파일 은 매우 간단 합 니 다.단 하나의 버튼 만 있 습 니 다.열 거나 새 activitymain.xml,
다음 코드 추가:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 xmlns:tools="http://schemas.android.com/tools" 
 android:layout_width="fill_parent" 
 android:layout_height="fill_parent" 
 tools:context=".MainActivity" > 
 <Button 
 android:id="@+id/start_float_window" 
 android:layout_width="fill_parent" 
 android:layout_height="wrap_content" 
 android:text="Start Float Window" > 
 </Button> 
</RelativeLayout> 
그리고 플 로 트 라 는 이름 을 새로 만 듭 니 다.window_small.xml 의 레이아웃 파일 은 작은 부상 창의 레이아웃 으로 사용 되 며,
다음 코드 를 추가 합 니 다:

<?xml version="1.0" encoding="UTF-8"?> 
<LinearLayout 
 xmlns:android="http://schemas.android.com/apk/res/android" 
 android:id="@+id/small_window_layout" 
 android:layout_width="60dip" 
 android:layout_height="25dip" 
 android:background="@drawable/bg_small" 
 > 
 <TextView 
 android:id="@+id/percent" 
 android:layout_width="fill_parent" 
 android:layout_height="fill_parent" 
 android:gravity="center" 
 android:textColor="#ffffff" 
 /> 
</LinearLayout> 
플 로 트 라 는 이름 을 새로 만 듭 니 다.window_big.xml 의 레이아웃 파일 은 큰 부상 창의 레이아웃 으로 사용 되 며,
다음 코드 를 추가 합 니 다:

<?xml version="1.0" encoding="UTF-8"?> 
<LinearLayout 
 xmlns:android="http://schemas.android.com/apk/res/android" 
 android:id="@+id/big_window_layout" 
 android:layout_width="200dip" 
 android:layout_height="100dip" 
 android:background="@drawable/bg_big" 
 android:orientation="vertical" 
 > 
 <Button 
 android:id="@+id/close" 
 android:layout_width="100dip" 
 android:layout_height="40dip" 
 android:layout_gravity="center_horizontal" 
 android:layout_marginTop="12dip" 
 android:text="     " 
 /> 
 <Button 
 android:id="@+id/back" 
 android:layout_width="100dip" 
 android:layout_height="40dip" 
 android:layout_gravity="center_horizontal" 
 android:text="  " 
 /> 
</LinearLayout> 
두 개의 부상 창 레이아웃 파일 에 사용 되 는 그림 자원 은 여러분 이 마음대로 그림 을 찾 아서 대체 할 수 있 습 니 다.그리고 저 는 소스 코드 를 드릴 것 입 니 다.여러분 도 소스 코드 에서 꺼 낼 수 있 습 니 다.
그리고 MainActivity 를 열거 나 만 듭 니 다.이것 은 프로젝트 의 메 인 인터페이스 입 니 다.
다음 코드 를 추가 합 니 다:

public class MainActivity extends Activity { 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
 super.onCreate(savedInstanceState); 
 setContentView(R.layout.activity_main); 
 Button startFloatWindow = (Button) findViewById(R.id.start_float_window); 
 startFloatWindow.setOnClickListener(new OnClickListener() { 
 @Override 
 public void onClick(View arg0) { 
 Intent intent = new Intent(MainActivity.this, FloatWindowService.class); 
 startService(intent); 
 finish(); 
 } 
 }); 
 } 
}
여기에서 볼 수 있 듯 이 MainActivity 의 코드 는 창 이 아 닌 간단 합 니 다.바로 부상 창 을 여 는 버튼 에 클릭 이 벤트 를 등록 하여 서 비 스 를 열 고 현재 Activity 를 닫 는 것 입 니 다.부상 창 을 만 드 는 논 리 는 모두 서비스 에 맡 겼 다.자,이제 이 서 비 스 를 만 들 겠 습 니 다.Float Window Service 라 는 클래스 를 새로 만 듭 니 다.이 클래스 는 Service 에서 계승 합 니 다.
다음 코드 를 추가 합 니 다:

public class FloatWindowService extends Service { 
 
 /** 
 *               。 
 */ 
 private Handler handler = new Handler(); 
 
 /** 
 *    ,                   。 
 */ 
 private Timer timer; 
 
 @Override 
 public IBinder onBind(Intent intent) { 
 return null; 
 } 
 
 @Override 
 public int onStartCommand(Intent intent, int flags, int startId) { 
 //      ,  0.5      
 if (timer == null) { 
 timer = new Timer(); 
 timer.scheduleAtFixedRate(new RefreshTask(), 0, 500); 
 } 
 return super.onStartCommand(intent, flags, startId); 
 } 
 
 @Override 
 public void onDestroy() { 
 super.onDestroy(); 
 // Service                 
 timer.cancel(); 
 timer = null; 
 } 
 
 class RefreshTask extends TimerTask { 
 
 @Override 
 public void run() { 
 //        ,        ,      。 
 if (isHome() && !MyWindowManager.isWindowShowing()) { 
 handler.post(new Runnable() { 
 @Override 
 public void run() { 
 MyWindowManager.createSmallWindow(getApplicationContext()); 
 } 
 }); 
 } 
 //         ,       ,      。 
 else if (!isHome() && MyWindowManager.isWindowShowing()) { 
 handler.post(new Runnable() { 
 @Override 
 public void run() { 
 MyWindowManager.removeSmallWindow(getApplicationContext()); 
 MyWindowManager.removeBigWindow(getApplicationContext()); 
 } 
 }); 
 } 
 //        ,       ,       。 
 else if (isHome() && MyWindowManager.isWindowShowing()) { 
 handler.post(new Runnable() { 
 @Override 
 public void run() { 
 MyWindowManager.updateUsedPercent(getApplicationContext()); 
 } 
 }); 
 } 
 } 
 
 } 
 
 /** 
 *             
 */ 
 private boolean isHome() { 
 ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 
 List<RunningTaskInfo> rti = mActivityManager.getRunningTasks(1); 
 return getHomes().contains(rti.get(0).topActivity.getPackageName()); 
 } 
 
 /** 
 *                 
 * 
 * @return                
 */ 
 private List<String> getHomes() { 
 List<String> names = new ArrayList<String>(); 
 PackageManager packageManager = this.getPackageManager(); 
 Intent intent = new Intent(Intent.ACTION_MAIN); 
 intent.addCategory(Intent.CATEGORY_HOME); 
 List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent, 
 PackageManager.MATCH_DEFAULT_ONLY); 
 for (ResolveInfo ri : resolveInfo) { 
 names.add(ri.activityInfo.packageName); 
 } 
 return names; 
 } 
} 
Float Window Service 의 onStart Command 방법 에서 타 이 머 를 켜 면 500 밀리초 마다 Refresh Task 를 실행 합 니 다.RefreshTask 에서 판단 을 하려 면 핸드폰 이 현재 데스크 톱 에 있다 면 부상 창 을 표시 해 야 한다.만약 에 핸드폰 이 어떤 프로그램 을 열 었 다 면 부상 창 을 제거 해 야 한다.만약 에 핸드폰 이 데스크 톱 에 있다 면 메모리 사용 백분율 의 데 이 터 를 업데이트 해 야 한다.Float Window Service 가 소각 되 었 을 때 타 이 머 를 멈 춰 야 합 니 다.그렇지 않 으 면 계속 실 행 될 것 입 니 다.
위의 코드 를 통 해 알 수 있 듯 이 부상 창 을 만 들 고 제거 하 며 부상 창 에 있 는 데 이 터 를 업데이트 하 는 것 은 모두 MyWindow Manager 와 같은 종류 로 관리 하 는 것 입 니 다.이 코드 를 Activity 나 Service 에 직접 쓰 는 것 보다 전문 적 인 도구 류 를 사용 하여 관리 하 는 것 이 좋 습 니 다.그러나 부상 창 을 만 들 려 면 먼저 부상 창의 View 를 써 야 한다.
Float Window SmallView 라 는 클래스 를 새로 만 들 고 LinearLayout 에서 계승 합 니 다.Float Window BigView 라 는 클래스 를 새로 만 들 고 LinearLayout 에서 도 계승 합 니 다.
Float Window SmallView 에 다음 코드 를 추가 합 니 다.

public class FloatWindowSmallView extends LinearLayout { 
 
 /** 
 *           
 */ 
 public static int viewWidth; 
 
 /** 
 *           
 */ 
 public static int viewHeight; 
 
 /** 
 *            
 */ 
 private static int statusBarHeight; 
 
 /** 
 *             
 */ 
 private WindowManager windowManager; 
 
 /** 
 *         
 */ 
 private WindowManager.LayoutParams mParams; 
 
 /** 
 *                   
 */ 
 private float xInScreen; 
 
 /** 
 *                   
 */ 
 private float yInScreen; 
 
 /** 
 *                   
 */ 
 private float xDownInScreen; 
 
 /** 
 *                   
 */ 
 private float yDownInScreen; 
 
 /** 
 *              View        
 */ 
 private float xInView; 
 
 /** 
 *              View        
 */ 
 private float yInView; 
 
 public FloatWindowSmallView(Context context) { 
 super(context); 
 windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
 LayoutInflater.from(context).inflate(R.layout.float_window_small, this); 
 View view = findViewById(R.id.small_window_layout); 
 viewWidth = view.getLayoutParams().width; 
 viewHeight = view.getLayoutParams().height; 
 TextView percentView = (TextView) findViewById(R.id.percent); 
 percentView.setText(MyWindowManager.getUsedPercentValue(context)); 
 } 
 
 @Override 
 public boolean onTouchEvent(MotionEvent event) { 
 switch (event.getAction()) { 
 case MotionEvent.ACTION_DOWN: 
 //            ,                
 xInView = event.getX(); 
 yInView = event.getY(); 
 xDownInScreen = event.getRawX(); 
 yDownInScreen = event.getRawY() - getStatusBarHeight(); 
 xInScreen = event.getRawX(); 
 yInScreen = event.getRawY() - getStatusBarHeight(); 
 break; 
 case MotionEvent.ACTION_MOVE: 
 xInScreen = event.getRawX(); 
 yInScreen = event.getRawY() - getStatusBarHeight(); 
 //                  
 updateViewPosition(); 
 break; 
 case MotionEvent.ACTION_UP: 
 //          ,xDownInScreen xInScreen  , yDownInScreen yInScreen  ,          。 
 if (xDownInScreen == xInScreen && yDownInScreen == yInScreen) { 
 openBigWindow(); 
 } 
 break; 
 default: 
 break; 
 } 
 return true; 
 } 
 
 /** 
 *           ,           。 
 * 
 * @param params 
 *         
 */ 
 public void setParams(WindowManager.LayoutParams params) { 
 mParams = params; 
 } 
 
 /** 
 *              。 
 */ 
 private void updateViewPosition() { 
 mParams.x = (int) (xInScreen - xInView); 
 mParams.y = (int) (yInScreen - yInView); 
 windowManager.updateViewLayout(this, mParams); 
 } 
 
 /** 
 *       ,        。 
 */ 
 private void openBigWindow() { 
 MyWindowManager.createBigWindow(getContext()); 
 MyWindowManager.removeSmallWindow(getContext()); 
 } 
 
 /** 
 *           。 
 * 
 * @return            。 
 */ 
 private int getStatusBarHeight() { 
 if (statusBarHeight == 0) { 
 try { 
 Class<?> c = Class.forName("com.android.internal.R$dimen"); 
 Object o = c.newInstance(); 
 Field field = c.getField("status_bar_height"); 
 int x = (Integer) field.get(o); 
 statusBarHeight = getResources().getDimensionPixelSize(x); 
 } catch (Exception e) { 
 e.printStackTrace(); 
 } 
 } 
 return statusBarHeight; 
 } 
그 중에서 이 View 의 onTouchEvent 이 벤트 를 다시 써 서 드래그 와 클릭 효 과 를 실현 합 니 다.사용자 가 ACTION 을 촉발 한 것 을 발견 하면DOWN 이벤트,눌 렀 을 때의 좌표 등 데 이 터 를 기록 합 니 다.사용자 가 ACTION 을 촉발 한 것 을 발견 하면MOVE 이 벤트 는 현재 이동 하 는 좌표 에 따라 화면 에 떠 있 는 창 위 치 를 업데이트 합 니 다.사용자 가 ACTION 을 촉발 한 것 을 발견 하면UP 이벤트,ACTIONDOWN 에 기 록 된 좌표 대 비 는 동일 한 것 을 발견 하면 사용자 가 부상 창 을 클릭 한 것 으로 간주한다.작은 부상 창 을 클릭 하면 큰 부상 창 을 열 고 큰 부상 창의 View 를 실현 합 니 다.
Float Window BigView 에 다음 코드 를 추가 합 니 다.

public class FloatWindowBigView extends LinearLayout { 
 
 /** 
 *           
 */ 
 public static int viewWidth; 
 
 /** 
 *           
 */ 
 public static int viewHeight; 
 
 public FloatWindowBigView(final Context context) { 
 super(context); 
 LayoutInflater.from(context).inflate(R.layout.float_window_big, this); 
 View view = findViewById(R.id.big_window_layout); 
 viewWidth = view.getLayoutParams().width; 
 viewHeight = view.getLayoutParams().height; 
 Button close = (Button) findViewById(R.id.close); 
 Button back = (Button) findViewById(R.id.back); 
 close.setOnClickListener(new OnClickListener() { 
 @Override 
 public void onClick(View v) { 
 //           ,       ,   Service 
 MyWindowManager.removeBigWindow(context); 
 MyWindowManager.removeSmallWindow(context); 
 Intent intent = new Intent(getContext(), FloatWindowService.class); 
 context.stopService(intent); 
 } 
 }); 
 back.setOnClickListener(new OnClickListener() { 
 @Override 
 public void onClick(View v) { 
 //        ,      ,       
 MyWindowManager.removeBigWindow(context); 
 MyWindowManager.createSmallWindow(context); 
 } 
 }); 
 } 
}
Float Window SmallView 보다 Float Window BigView 는 두 개의 버튼 만 있 고 close 단 추 를 누 르 면 부상 창 을 모두 제거 하고 Service 를 종료 합 니 다.back 단 추 를 누 르 면 큰 부상 창 을 제거 하고 작은 부상 창 을 다시 만 듭 니 다.
현재 두 개의 부상 창의 View 가 모두 작성 되 었 습 니 다.MyWindow Manager 를 만 들 겠 습 니 다.
코드 는 다음 과 같 습 니 다:

public class MyWindowManager { 
 
 /** 
 *     View    
 */ 
 private static FloatWindowSmallView smallWindow; 
 
 /** 
 *     View    
 */ 
 private static FloatWindowBigView bigWindow; 
 
 /** 
 *     View    
 */ 
 private static LayoutParams smallWindowParams; 
 
 /** 
 *     View    
 */ 
 private static LayoutParams bigWindowParams; 
 
 /** 
 *                  
 */ 
 private static WindowManager mWindowManager; 
 
 /** 
 *            
 */ 
 private static ActivityManager mActivityManager; 
 
 /** 
 *         。              。 
 * 
 * @param context 
 *         Context. 
 */ 
 public static void createSmallWindow(Context context) { 
 WindowManager windowManager = getWindowManager(context); 
 int screenWidth = windowManager.getDefaultDisplay().getWidth(); 
 int screenHeight = windowManager.getDefaultDisplay().getHeight(); 
 if (smallWindow == null) { 
 smallWindow = new FloatWindowSmallView(context); 
 if (smallWindowParams == null) { 
 smallWindowParams = new LayoutParams(); 
 smallWindowParams.type = LayoutParams.TYPE_PHONE; 
 smallWindowParams.format = PixelFormat.RGBA_8888; 
 smallWindowParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL 
 | LayoutParams.FLAG_NOT_FOCUSABLE; 
 smallWindowParams.gravity = Gravity.LEFT | Gravity.TOP; 
 smallWindowParams.width = FloatWindowSmallView.viewWidth; 
 smallWindowParams.height = FloatWindowSmallView.viewHeight; 
 smallWindowParams.x = screenWidth; 
 smallWindowParams.y = screenHeight / 2; 
 } 
 smallWindow.setParams(smallWindowParams); 
 windowManager.addView(smallWindow, smallWindowParams); 
 } 
 } 
 
 /** 
 *            。 
 * 
 * @param context 
 *         Context. 
 */ 
 public static void removeSmallWindow(Context context) { 
 if (smallWindow != null) { 
 WindowManager windowManager = getWindowManager(context); 
 windowManager.removeView(smallWindow); 
 smallWindow = null; 
 } 
 } 
 
 /** 
 *         。        。 
 * 
 * @param context 
 *         Context. 
 */ 
 public static void createBigWindow(Context context) { 
 WindowManager windowManager = getWindowManager(context); 
 int screenWidth = windowManager.getDefaultDisplay().getWidth(); 
 int screenHeight = windowManager.getDefaultDisplay().getHeight(); 
 if (bigWindow == null) { 
 bigWindow = new FloatWindowBigView(context); 
 if (bigWindowParams == null) { 
 bigWindowParams = new LayoutParams(); 
 bigWindowParams.x = screenWidth / 2 - FloatWindowBigView.viewWidth / 2; 
 bigWindowParams.y = screenHeight / 2 - FloatWindowBigView.viewHeight / 2; 
 bigWindowParams.type = LayoutParams.TYPE_PHONE; 
 bigWindowParams.format = PixelFormat.RGBA_8888; 
 bigWindowParams.gravity = Gravity.LEFT | Gravity.TOP; 
 bigWindowParams.width = FloatWindowBigView.viewWidth; 
 bigWindowParams.height = FloatWindowBigView.viewHeight; 
 } 
 windowManager.addView(bigWindow, bigWindowParams); 
 } 
 } 
 
 /** 
 *            。 
 * 
 * @param context 
 *         Context. 
 */ 
 public static void removeBigWindow(Context context) { 
 if (bigWindow != null) { 
 WindowManager windowManager = getWindowManager(context); 
 windowManager.removeView(bigWindow); 
 bigWindow = null; 
 } 
 } 
 
 /** 
 *        TextView    ,          。 
 * 
 * @param context 
 *           。 
 */ 
 public static void updateUsedPercent(Context context) { 
 if (smallWindow != null) { 
 TextView percentView = (TextView) smallWindow.findViewById(R.id.percent); 
 percentView.setText(getUsedPercentValue(context)); 
 } 
 } 
 
 /** 
 *       (           )      。 
 * 
 * @return             true,      false。 
 */ 
 public static boolean isWindowShowing() { 
 return smallWindow != null || bigWindow != null; 
 } 
 
 /** 
 *   WindowManager    ,       WindowManager  。          WindowManager。 
 * 
 * @param context 
 *         Context. 
 * @return WindowManager   ,                。 
 */ 
 private static WindowManager getWindowManager(Context context) { 
 if (mWindowManager == null) { 
 mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
 } 
 return mWindowManager; 
 } 
 
 /** 
 *   ActivityManager    ,       ActivityManager  。          ActivityManager。 
 * 
 * @param context 
 *           。 
 * @return ActivityManager   ,          。 
 */ 
 private static ActivityManager getActivityManager(Context context) { 
 if (mActivityManager == null) { 
 mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 
 } 
 return mActivityManager; 
 } 
 
 /** 
 *            ,   。 
 * 
 * @param context 
 *           。 
 * @return          ,        。 
 */ 
 public static String getUsedPercentValue(Context context) { 
 String dir = "/proc/meminfo"; 
 try { 
 FileReader fr = new FileReader(dir); 
 BufferedReader br = new BufferedReader(fr, 2048); 
 String memoryLine = br.readLine(); 
 String subMemoryLine = memoryLine.substring(memoryLine.indexOf("MemTotal:")); 
 br.close(); 
 long totalMemorySize = Integer.parseInt(subMemoryLine.replaceAll("\\D+", "")); 
 long availableSize = getAvailableMemory(context) / 1024; 
 int percent = (int) ((totalMemorySize - availableSize) / (float) totalMemorySize * 100); 
 return percent + "%"; 
 } catch (IOException e) { 
 e.printStackTrace(); 
 } 
 return "   "; 
 } 
 
 /** 
 *         ,          。 
 * 
 * @param context 
 *           。 
 * @return       。 
 */ 
 private static long getAvailableMemory(Context context) { 
 ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo(); 
 getActivityManager(context).getMemoryInfo(mi); 
 return mi.availMem; 
 } 
 
} 
이 종 류 는 큰 부상 창 을 제어 하고 작은 부상 창의 생 성과 제거,시스템 메모리 사용 백분율 의 계산 등 을 책임 진다.
여기까지 기본 적 인 모든 코드 를 다 썼 습 니 다.그리고 AndroidManifest.xml 파일 을 살 펴 보 겠 습 니 다.
내부 코드 는 다음 과 같 습 니 다.

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
 package="com.demo.floatwindowdemo" 
 android:versionCode="1" 
 android:versionName="1.0" > 
 
 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 
 
 <uses-sdk 
 android:minSdkVersion="8" 
 android:targetSdkVersion="8" /> 
 
 <application 
 android:allowBackup="true" 
 android:icon="@drawable/ic_launcher" 
 android:label="@string/app_name" 
 android:theme="@style/AppTheme" > 
 <activity 
 android:name="com.demo.floatwindowdemo.MainActivity" 
 android:label="@string/app_name" > 
 <intent-filter> 
 <action android:name="android.intent.action.MAIN" /> 
 
 <category android:name="android.intent.category.LAUNCHER" /> 
 </intent-filter> 
 </activity> 
 
 <service android:name=".FloatWindowService"></service> 
 </application> 
 
</manifest> 
간단 합 니 다.Activity 와 Service 를 안에 등록 하고 추가 해 야 할 권한 성명 도 있 습 니 다android.permission.SYSTEM_ALERT_WINDOW사용자 권한 이 필요 하 다 는 것 은 시스템 알림 창,즉 데스크 톱 부상 창 을 만 들 수 있 도록 해 야 한 다 는 것 을 의미 합 니 다.
자,이제 프로젝트 를 실행 합 시다.효 과 는 다음 그림 과 같 습 니 다.메 인 화면 에는 간단 한 버튼 만 있 습 니 다.단 추 를 누 르 면 Activity 가 닫 히 고 작은 부상 창 이 데스크 톱 에 표 시 됩 니 다.현재 메모리 에 사용 되 는 백분율 을 표시 합 니 다.
            
작은 부상 창 은 자 유 롭 게 끌 수 있 습 니 다.다른 프로그램 을 열 면 작은 부상 창 이 자동 으로 숨겨 지고 데스크 톱 으로 돌아 가면 작은 부상 창 이 표 시 됩 니 다.
           
작은 부상 창 을 누 르 면 큰 부상 창 이 튀 어 나 옵 니 다.여기 서 우리 의 큰 부상 창 은 비교적 간단하게 만 들 수 있 습 니 다.단 두 개의 버튼 만 있 습 니 다.큰 부상 창 이 전 시 될 때 휴대 전화의 모든 다른 프로그램 은 점 을 찍 을 수 없다.왜냐하면 초점 이 부상 창 에 있 기 때문이다.되 돌아 가기 단 추 를 누 르 면 작은 부상 창 을 다시 보 여주 고 부상 창 닫 기 단 추 를 누 르 면 Service 도 함께 멈춘다.

360 핸드폰 가 디 언 의 원 클릭 가속 기능 은 하지 않 겠 습 니 다.독고 구 검 처럼 중요 한 것 은 검 의 의미 가 아니 라 검 의 의미 입 니 다.저 는 여러분 들 이 부상 창 을 만 드 는 기본 원 리 를 배 워 서 360 보다 더 창의 적 인 것 을 만 들 수 있 을 것 이 라 고 믿 습 니 다.
질문 이 있 으 시 면 아래 에 메 시 지 를 남 겨 주세요.
데스크 톱 부상 창 에 관심 이 있 는 친 구 는 계속 읽 을 수 있 습 니 다.
안 드 로 이 드 데스크 톱 부상 창 진급
보충:친구 가 저 에 게 반응 을 했 습 니 다.위의 코드 가 안 드 로 이 드 3.0 이상 의 시스템 에서 실 행 될 때 무 너 질 것 입 니 다.제 가 봤 는데 그렇습니다.주로 3.0 이후 에 실행 중인 작업 을 얻 으 려 면 권한 성명 을 추가 해 야 합 니 다.AndroidManifest.xml 에 추가<uses-permission android:name="android.permission.GET_TASKS" /> 이 문 제 를 해결 할 수 있다.

좋은 웹페이지 즐겨찾기