Android启动无黑屏

1. 简介

    Android启动无黑屏是通过设置Window透明来实现的。主要是通过定义启动Activity的android:theme来实现的,但android:theme的定义是有要求的。

    本方法可以实现以下两项要求:

    1)启动无黑屏

    2)启动画面全屏显示

2. 实现方案

    res下目录结构:


2.1 AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="cn.xxx.gaoxueya"
      android:versionCode="1"
      android:versionName="1.0"
      android:installLocation="auto">

    <uses-sdk android:minSdkVersion="9"/>
    <uses-feature android:glEsVersion="0x00020000" />

    <application android:label="@string/app_name"
                 android:icon="@drawable/icon">
					 
        <!-- Tell Cocos2dxActivity the name of our .so -->
        <meta-data android:name="android.app.lib_name"
	              android:value="cocos2dcpp" />

        <activity android:name="org.cocos2dx.cpp.AppActivity"
                  android:label="@string/app_name"
                  android:screenOrientation="landscape"
                  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
                  android:configChanges="orientation">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        
        <activity android:name="cn.toltech.gaoxueya.SplashScreen"
                  android:theme="@style/Theme.Transparent">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"></action>
                <category android:name="android.intent.category.LAUNCHER"></category>
            </intent-filter>
        </activity>        
    </application>

    <supports-screens android:anyDensity="true"
                      android:smallScreens="true"
                      android:normalScreens="true"
                      android:largeScreens="true"
                      android:xlargeScreens="true"/>

    <uses-permission android:name="android.permission.INTERNET"/>
</manifest> 

2.2 styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<style name="Animations" parent="@android:Animation" />
	<style name="Animations.SplashScreen">
        <item name="android:windowEnterAnimation">@anim/appear</item>
        <item name="android:windowExitAnimation">@anim/disappear</item> 
    </style> 
	<style name="Theme.Transparent" parent="android:style/Theme.NoTitleBar.Fullscreen">
		<item name="android:windowIsTranslucent">true</item>
		<item name="android:windowBackground">@android:color/transparent</item>
		<item name="android:backgroundDimEnabled">false</item>
		<item name="android:windowNoTitle">true</item>
		<item name="android:windowContentOverlay">@null</item>
		<item name="android:windowAnimationStyle">@style/Animations.SplashScreen</item>				
	</style>		
</resources>

    若在Theme.Transparent中增加了<item name="android:windowIsFloating">true</item>,则此Activity无法全屏显示。


2.3  appear.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
	<alpha
		android:interpolator="@android:anim/accelerate_interpolator"
		android:fromAlpha="1.0" android:toAlpha="1.0"
		android:duration="800"
	/>
</set>

    可根据效果需要设置fromAlpha和toAlpha的值。


2.4 disappear.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
	<alpha
		android:interpolator="@android:anim/decelerate_interpolator"
		android:fromAlpha="1.0" android:toAlpha="1.0"
		android:duration="800"
	/>
</set>
    可根据效果需要设置fromAlpha和toAlpha的值。


2.5 splash.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent" 
  android:background="#FF0000"  
  android:orientation="vertical" 
  >
    <ImageView 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:src="@drawable/lnxins"        
        >
    </ImageView>
</LinearLayout>

2.6 SplashScreen.java

package cn.toltech.gaoxueya;;

import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.Menu;
import android.view.MotionEvent;
import android.widget.ImageView;

public class SplashScreen extends Activity {
    
    /**
     * The thread to process splash screen events
     */
    private Thread mSplashThread;    

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Splash screen view
        setContentView(R.layout.splash);
        
        final SplashScreen sPlashScreen = this;   
        
        // The thread to wait for splash screen events
        mSplashThread =  new Thread(){
            @Override
            public void run(){
                try {
                    synchronized(this){
                        // Wait given period of time or exit on touch
                        wait(5000);
                    }
                }
                catch(InterruptedException ex){                    
                }

                finish();
                
                // Run next activity
                Intent intent = new Intent();
                intent.setClass(sPlashScreen, org.cocos2dx.cpp.AppActivity.class);
                startActivity(intent);
                //stop();                    
            }
        };
        
        mSplashThread.start();        
    }
        
    /**
     * Processes splash screen touch events
     */
    @Override
    public boolean onTouchEvent(MotionEvent evt)
    {
        if(evt.getAction() == MotionEvent.ACTION_DOWN)
        {
            synchronized(mSplashThread){
                mSplashThread.notifyAll();
            }
        }
        return true;
    }    
}


2.7 AppActivity.java

package org.cocos2dx.cpp;

import org.cocos2dx.lib.Cocos2dxActivity;

// added by xxx on 2014.10.28
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import android.os.Bundle;
import android.view.SurfaceHolder;  
import android.view.SurfaceView;  
import android.view.View;  
import android.media.MediaPlayer;  
import android.util.Log;  
import java.io.IOException;  
import android.os.Message;
import android.os.Handler;


public class AppActivity extends Cocos2dxActivity {
    private static final String TAG="XXX";  

	private final static int HANDLER_MEDIA_PLAY 	= 1;
	private final static int HANDLER_MEDIA_STOP 	= 2;
	private final static int HANDLER_MEDIA_PAUSE 	= 3;
	private final static int HANDLER_MEDIA_RESUME 	= 4;
	private final static int HANDLER_MEDIA_SEEK 	= 5;
	

	private static Handler sHandler;
	private boolean mPlayerPaused = false;
	  
    private SurfaceHolder mediaSurfaceHolder = null;  
    private MediaPlayer   mMediaPlayer = null;  
	private GetPosThread  mPosThread = null;
    //private boolean isMediaPlay = false;  

	private String mCurrentPath = null;
	private int    mCurrentCount = 0;
      
    protected void onCreate(Bundle savedInstanceState){  
        super.onCreate(savedInstanceState);   
        initMedia();  
    }  

	/*  	
    public Cocos2dxGLSurfaceView onCreateView() {  
        Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);  
        // Demo2 should create stencil buffer  
        glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);  
          
        return glSurfaceView;  
    }
  
    private void initVideo(){  
        mediaSurfaceHolder = mMediaPlayView.getHolder();  
        mediaSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
        mediaSurfaceHolder.addCallback(new MediaSurfaceHolderCallBack());  
    }*/

	private void initMedia(){
    	mediaSurfaceHolder = mMediaPlayView.getHolder();
    	mediaSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    	mediaSurfaceHolder.addCallback(new MediaSurfaceHolderCallBack());
        
		this.sHandler = new Handler() {
			@Override
			public void handleMessage(final Message msg) {
				switch (msg.what) {
                    
					case HANDLER_MEDIA_PLAY:
                        // set MediaPlayer status
                        mPlayerPaused = false;
                        
                        final String path = (String) msg.obj;
                        final int playNum = msg.arg1;

                        Log.d(TAG,"HANDLER_VIDEO_PLAY:" + "path=" + path + ", playNum=" + playNum);

                        // stop the thread that get cur position
                        if(mPosThread != null){
							mPosThread.stopThread(true);
							mPosThread = null;
                    	}
                        //if(mServer != null) mServer.stopHandler();

                        if (mMediaPlayer != null) {
                            mMediaPlayer.stop();
                        
                            // should set the state, if not, the following sequence will be error
                            // play -> pause -> stop -> resume
                            mPlayerPaused = false;
                        }

                        
                        if (mCurrentPath == null) {
                            // it is the first time to play media 
                            mMediaPlayer = createMediaPlayer(path);

                            // record the path and play number
                            if(mMediaPlayer != null){
                                mCurrentPath = path;
                                mCurrentCount = playNum;
                            }
                            
                        } else {
							// play new media or replay
							// release old resource and create a new one
							if (mMediaPlayer != null) {
							    mMediaPlayer.release();
							}

							mMediaPlayer = createMediaPlayer(path);

							// record the path and play number
							if(mMediaPlayer != null){
							    mCurrentPath = path;
							    mCurrentCount = playNum;
							}
                        }
                        
                        if (mMediaPlayer == null) {
                            Log.e(TAG, "ERROR: media player is null");
                        }
                        
						break;
                        
					case HANDLER_MEDIA_SEEK:
                        Log.d(TAG,"receive HANDLER_VIDEO_SEEK");
                        
						if((null != mMediaPlayer)&&(mMediaPlayer.isPlaying() || mPlayerPaused)){
                            mMediaPlayer.seekTo(msg.arg1);    
                            Log.d(TAG,"seekTo:" + msg.arg1 + "ms");
                        }
                        
						break;
					case HANDLER_MEDIA_STOP:
                        Log.d(TAG,"receive HANDLER_VIDEO_STOP");

                        // stop the thread that get cur position
                        if(mPosThread != null){
							mPosThread.stopThread(true);
							mPosThread = null;
                    	}
                        //if(mServer != null) mServer.stopHandler();

                        if (mMediaPlayer != null) {
                            mMediaPlayer.stop();
                        
                            // should set the state, if not, the following sequence will be error
                            // play -> pause -> stop -> resume
                            mPlayerPaused = false;
                        }
						break;
                        
					case HANDLER_MEDIA_PAUSE:
                        Log.d(TAG,"receive HANDLER_VIDEO_PAUSE");
                        
                        if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
                            mMediaPlayer.pause();
                            mPlayerPaused = true;
                        }
						break;

					case HANDLER_MEDIA_RESUME:
                        Log.d(TAG,"receive HANDLER_VIDEO_RESUME");
                        
                        if (mMediaPlayer != null && mPlayerPaused) {
                            mMediaPlayer.start();
                            mPlayerPaused = false;
                        }

						break;                        
				}
			}
		};        
	}
		
	public class GetPosThread extends Thread {
	
		private boolean  _run  = true;
		public void stopThread( boolean  run) {
			this ._run = !run;
		}
		
		@Override
		public void run() {
			while(_run) {
				try {
					if((mMediaPlayer != null) && (mMediaPlayer.isPlaying())){
					
						int pos = mMediaPlayer.getCurrentPosition();
						nativeUpdateCurPos(pos);
					}
					else
					{
						if(mMediaPlayer == null) Log.d(TAG, "mMediaPlayer is null");
						//if(mMediaPlayer.isPlaying()!= true) Log.d(TAG,"mMediaPlayer is not playing");
					}
					
					Thread.sleep(1000); // sleep 1s
					
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	
	}

	private MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
		@Override
		public void onPrepared(MediaPlayer mp) {
			Log.d(TAG,"onPrepared...");
			mediaSurfaceHolder.setFixedSize(mp.getVideoWidth(), mp.getVideoHeight());

			// start play video
			mp.start();
  
	    	try{
	    		// startup Get Pos Thread
	    		mPosThread = new GetPosThread();
	    		mPosThread.start(); 
		    } catch (Exception e) {
		    	e.printStackTrace();
		    }
		}
	};

	private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
		public void onCompletion(MediaPlayer mp) {
			Log.d(TAG,"onCompletion...");

            if(mCurrentCount == -1){
    			mp.seekTo(0);
    			mp.start();
            }else{
                // stop the thread that get cur position
                if(mPosThread != null) mPosThread.stopThread(true);

				// notify stop video play
                nativePlayEnd();
            }
		}
	};

      
    private class MediaSurfaceHolderCallBack implements SurfaceHolder.Callback{  
  
        @Override  
        public void surfaceChanged(SurfaceHolder holder, int format, int width,  
                int height) {  
            Log.d(TAG,"surfaceChanged...,width="+width+", height="+height);  
              
        }  
  
        @Override  
        public void surfaceCreated(SurfaceHolder holder) {  
  
            Log.d(TAG,"surfaceCreated...");  
            play("/mnt/sdcard/video/cg720p.mp4");
            /*  
            mMediaPlayer = new MediaPlayer();  
            mMediaPlayer.setOnPreparedListener(mPreparedListener);  
            mMediaPlayer.setOnCompletionListener(mCompletionListener);  
              
            try {  
                mMediaPlayer.setDataSource("/sdcard/video/cg.mp4");  
            } catch (IllegalArgumentException e) {  
                e.printStackTrace();  
            } catch (IllegalStateException e) {  
                e.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
            mMediaPlayer.setDisplay(mediaSurfaceHolder);  
              
            try {  
                mMediaPlayer.prepareAsync();   
            } catch (IllegalStateException e) {  
                e.printStackTrace();  
            } */  
        }  
  
        @Override  
        public void surfaceDestroyed(SurfaceHolder holder) {  
            if( mMediaPlayer != null && mMediaPlayer.isPlaying() ){  
                mMediaPlayer.stop();  
                mMediaPlayer.release();  
                mMediaPlayer = null;  
            }  
  
            if( mediaSurfaceHolder != null ){  
                mediaSurfaceHolder = null;  
            }  
        }  
    }  
          
	private MediaPlayer createMediaPlayer(final String path) {
		MediaPlayer mediaPlayer = new MediaPlayer();
		
		mediaPlayer.setOnPreparedListener(mPreparedListener);
		mediaPlayer.setOnCompletionListener(mCompletionListener);
		mediaPlayer.setDisplay(mediaSurfaceHolder);

		try {
			mediaPlayer.setDataSource(path);
			mediaPlayer.prepareAsync();
		} catch (final Exception e) {
			mediaPlayer = null;
			Log.e(TAG, "error: " + e.getMessage(), e);
		}

		return mediaPlayer;
	}

	// Video Player Interface with C++
	public static boolean play(final String path) {
		Log.d(TAG,"receive native play: path=" +path);

		final Message msg = new Message();
		msg.what = HANDLER_MEDIA_PLAY;
		msg.obj = path;
		msg.arg1 = 1;
		
		sHandler.sendMessage(msg);

		return true;
	}

	public static boolean seekTo(int msec){
		Log.d(TAG,"receive native seekTo: msec=" +msec);

		final Message msg = new Message();
		msg.what = HANDLER_MEDIA_SEEK;
		msg.arg1 = msec;
		
		sHandler.sendMessage(msg);
		return true;
	}

	public static boolean stop(){
		Log.d(TAG,"receive native stop");
		
		final Message msg = new Message();
		msg.what = HANDLER_MEDIA_STOP;
		sHandler.sendMessage(msg);
		
		return true;		  
	}

	public static boolean pause(){
		Log.d(TAG,"receive native pause");
		
		final Message msg = new Message();
		msg.what = HANDLER_MEDIA_PAUSE;
		sHandler.sendMessage(msg);
		
		return true;		  
	}

	public static boolean resume(){
		Log.d(TAG,"receive native resume");
		
		final Message msg = new Message();
		msg.what = HANDLER_MEDIA_RESUME;
		sHandler.sendMessage(msg);
		
		return true;		  
	}

	// Native method
	private static native void nativeUpdateCurPos(int curPos);
	private static native void nativePlayEnd();

}


更简单的方式:http://www.cnblogs.com/liqw/p/4263418.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值