• android为应用程序添加退出动画


    
    

    原本想搞一个退出程序时,把前一个应用程序的VIEW或者截图抓过来为我用,以实现更复杂的动画效果,尝试了很多方法,但都有或多或少的缺陷,可惜最后失败了。不过也算有所得。写文以标记。

    其实抓图在4.0以后的版本中,还是很容易实现的,因为系统有十分完美的自带的截图。只要有源码,可以修改系统,通过执行screencap 和screenshot命令可以实现。

    public static boolean RootCommand(String command)   //申请root权限
    	    {
    	        Process process = null;
    	        DataOutputStream os = null;
    	        try
    	        {
    	            process = Runtime.getRuntime().exec("su");
    	            os = new DataOutputStream(process.getOutputStream());
    	            os.writeBytes(command + "
    ");
    	            os.writeBytes("exit
    ");
    	            os.flush();
    	            process.waitFor();
    	        } catch (Exception e)
    	        {
    	            Log.d("*** DEBUG ***", "ROOT REE" + e.getMessage());
    	            return false;
    	        } finally
    	        {
    	            try
    	            {
    	                if (os != null)
    	                {
    	                    os.close();
    	                }
    	                process.destroy();
    	            } catch (Exception e)
    	            {
    	            }
    	        }
    	        Log.d("*** DEBUG ***", "Root SUC ");
    	        return true;
    	    }


    通过调用系统的截屏程序也能实现。如果要实现进入自己的软件前获得屏幕BUFFER,下面的函数可以实现,返回的BITMAP就是前一屏的BITMAP,不过如果抓图是竖屏,进入自己的程序后变横屏,这个图就没办法变横了。因为我是需要在锁屏时,把前一屏数据结果锁屏做一个动画,所以如果解锁时,前一窗口数据已经变化,这个载屏就没什么用处了。无法实现解锁窗口与前一程序无缝衔接。同时如果你的锁屏如果是在黑屏后才进入,那么这个裁屏截到的也是黑屏了,大家都懂的。

    public Bitmap getScreenBuffer()
    	{
    		Display mDisplay;
    		DisplayMetrics mDisplayMetrics;
    		Matrix mDisplayMatrix = new Matrix();
    
    		WindowManager mWindowManager = (WindowManager) mContext
    				.getSystemService(Context.WINDOW_SERVICE);
    		mDisplay = mWindowManager.getDefaultDisplay();
    		mDisplayMetrics = new DisplayMetrics();
    		mDisplay.getRealMetrics(mDisplayMetrics);
    		mDisplay.getRealMetrics(mDisplayMetrics);
    		float[] dims = { mDisplayMetrics.widthPixels,
    				mDisplayMetrics.heightPixels };
    		
    		mlock = Surface.screenshot((int) dims[0], (int) dims[1]);
    		return mlock;
    	}

    截屏函数在上锁时,由于会黑屏,结果只能抓到黑屏图,所以可以通过调用4.0以后最近运行的程序的快照来替代,大概是ActivityManager.java 中getTaskThumbnails(int)}.但由于我的需要支持横竖屏,所以当解锁前后横竖屏状态不同时,这个快照也失去了意义。

    那么只剩下最后一种方式,获得上一次运行的activity的实例,进而获得其getDecorView,把其getDecorView转为BITMAP来运用。获得前一次运行的程序,可以通过以下代码获取:

    ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    		List<RunningTaskInfo> cn = am.getRunningTasks(2);
    		RunningTaskInfo taskInfo = cn.get(1);
    		ComponentName name = taskInfo.topActivity;
    		Log.i("jia @@@@@@", "name.getClassName() = "+name.getClassName());
    		Log.i("jia @@@@@@", "name.getPackageName() = "+name.getPackageName());
    		Log.i("jia @@@@@@", "name.getClass() = "+name.getClass().toString());
    		Log.i("jia @@@@@@", "name.getShortClassName() = "+name.getShortClassName());
    getRunningTasks可以获得当前运行的程序,参数2为获得最近两个程序,
    cn.get(1);为获得倒数第二个运行的程序,如果参数为0,就是当前程序


    然后使用动态加载反射其activity

    Context cc = null;
            try {
                cc = this.createPackageContext(name.getPackageName(), Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
            } catch (NameNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }  
            //载入这个类  
            Class clazz = null;
            try {
                clazz = cc.getClassLoader().loadClass(name.getClassName());
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }  
            Activity aa = null;
            try {
                aa = (Activity)clazz.newInstance();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        Intent in = new Intent(cc, clazz);
            in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
            this.startActivity(in);
            overridePendingTransition(android.R.anim.slide_in_left,   
                    android.R.anim.slide_out_right); 

    最后,完整的代码

    package com.example.testtaskactivity;
    
    import java.util.List;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.app.ActivityGroup;
    import android.app.ActivityManager;
    import android.app.ActivityManager.RunningTaskInfo;
    import android.app.LocalActivityManager;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager.NameNotFoundException;
    import android.graphics.Rect;
    import android.util.Log;
    import android.view.Menu;
    import android.view.View;
    import android.view.Window;
    import android.widget.RelativeLayout.LayoutParams;
    
    public class MainActivity extends ActivityGroup {
    	private LocalActivityManager localActivityManager = null;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    	}
    
    	@Override
    	public boolean onCreateOptionsMenu(Menu menu) {
    		// Inflate the menu; this adds items to the action bar if it is present.
    		getMenuInflater().inflate(R.menu.main, menu);
    		return true;
    	}
    
    	public void gettaskview(View view) {
    		ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    		List<RunningTaskInfo> cn = am.getRunningTasks(2);
    		RunningTaskInfo taskInfo = cn.get(1);
    		ComponentName name = taskInfo.topActivity;
    		Log.i("jia @@@@@@", "name.getClassName() = " + name.getClassName());
    		Log.i("jia @@@@@@", "name.getPackageName() = " + name.getPackageName());
    		Log.i("jia @@@@@@", "name.getClass() = " + name.getClass().toString());
    		Log.i("jia @@@@@@",
    				"name.getShortClassName() = " + name.getShortClassName());
    		Activity a = null;
    		Class c = null;
    
    		/*
    		 * try { c = Class.forName(name.getClassName()); Log.i("jia @@@@@@",
    		 * "c =  "+c.getName().toString()); } catch (ClassNotFoundException e) {
    		 * // TODO Auto-generated catch block e.printStackTrace();
    		 * Log.i("jia @@@@@@", "11111111111111111 "); } try { a =
    		 * (Activity)c.newInstance(); Log.i("jia @@@@@@", "a =  "+a.toString());
    		 * } catch (InstantiationException e) { // TODO Auto-generated catch
    		 * block e.printStackTrace(); } catch (IllegalAccessException e) { //
    		 * TODO Auto-generated catch block e.printStackTrace(); }
    		 */
    		/*
    		 * View currentScreen = a.getWindow().getDecorView();
    		 * 
    		 * this.addContentView(currentScreen, new LayoutParams(
    		 * LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    		 */
    		// this.createPackageContext(packageName, flags);
    		Context cc = null;
    		try {
    			cc = this.createPackageContext(name.getPackageName(),
    					Context.CONTEXT_INCLUDE_CODE
    							| Context.CONTEXT_IGNORE_SECURITY);
    		} catch (NameNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		// 载入这个类
    		Class clazz = null;
    		try {
    			clazz = cc.getClassLoader().loadClass(name.getClassName());
    		} catch (ClassNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		Activity aa = null;
    		try {
    			aa = (Activity) clazz.newInstance();
    		} catch (InstantiationException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		// PolicyManager.makeNewWindow(context);
    		// View v = aa.getWindow().getDecorView();
    		// setContentView(v);
    		Intent in = new Intent(cc, clazz);
    		in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
    				| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    		this.startActivity(in);
    		overridePendingTransition(android.R.anim.slide_in_left,
    				android.R.anim.slide_out_right);
    		/*
    		 * Rect frame = new Rect();
    		 * getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); int
    		 * statusBarHeight = frame.top; Log.i("jia @@@@@@",
    		 * "statusBarHeight =  " + statusBarHeight);
    		 * 
    		 * 
    		 * LocalActivityManager mgr = this.getLocalActivityManager();
    		 * Intent in
    		 * = new Intent(this, clazz); in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
    		 * | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); Window w =
    		 * mgr.startActivity("aaa", in); View v =w.getDecorView(); //View v =
    		 * a.getWindow().getDecorView(); setContentView(v);
    		 */
    
    	}
    
    }
    


    这样可以使唤得我们可以在不同的应用之间使用动画跳转,但我尝试使用Window w = mgr.startActivity("aaa", in)获得前一activity的VIEW时,提示该activity没有在我的

    AndroidManifest.xml中声明,第三方的和系统的应用,本不该在我的应用中声明,可能是因为别人的VIEW不能为我所用吧。抓图程序需要system权限,需要在AndroidManifest.xml文件的manifest标签中声明,android:sharedUserId="android.uid.system"。要不抓不了图,也获取不了屏幕的bitmap,Surface.screenshot函数是系统的隐藏API,不可在APK中直接使用,需要写一个如下的MK文件,放在源码目录下使用MM编绎:

    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)

    LOCAL_MODULE_TAGS := optional

    LOCAL_JAVA_LIBRARIES := bouncycastle
                            framework   
                            mediatek-framework

    LOCAL_CERTIFICATE := platform

    LOCAL_STATIC_JAVA_LIBRARIES :=
        android-support-v4

    LOCAL_SRC_FILES := $(call all-java-files-under, src)

    LOCAL_PACKAGE_NAME := Scr


    #LOCAL_SDK_VERSION := current

    include $(BUILD_PACKAGE)

    # Use the following include to make our test apk.
    include $(call all-makefiles-under,$(LOCAL_PATH))

    本文不可转载,需注明出处:

    http://blog.csdn.net/cnbloger/article/details/10029633

  • 相关阅读:
    采用软件负载均衡器实现web服务器集群
    MS Server 定时备份
    项目失败的若干征兆
    理解SQL Server中的权限体系
    项目管理思考 权利
    基于'sessionStorage'与'userData'的类session存储
    Fit健身APP与HarmonyOS创新合作 打造全新在线健身体验
    #2020征文手机#HarmonyOS轻量级偏好数据库初体验
    鸿蒙HarmonyOS应用开发落地实践,Harmony Go 技术沙龙落地北京
    【2021年1月16日公开课】分布式家庭记账本Demo分享,干货满满!
  • 原文地址:https://www.cnblogs.com/james1207/p/3265173.html
Copyright © 2020-2023  润新知