Issue
I want to modify the existing Android demo application 3D Rubik cube that uses GLSurfaceView, and when launched, the Rubik cube should render in a translucent way. The Rubik cube should not respond to any touch event and all the touch event should be passed down to the underlying application. While the 3D Rubik cube is rendering on the screen, I should be able to use the device in a normal way.
Till now I am able to run the Rubik cube on top of main menu, but it doesn't allow any touch event to get pass to the underlying applications. Also the 3D cube exit on pressing back key(not the desired result I want). I am running Android 4.0.3.
public class KubeService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("KubeService", "Received start id " + startId + ": " + intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onCreate() {
super.onCreate();
Intent intent1 = new Intent();
intent1.setComponent(new ComponentName("com.abc.appname","com.abc.appname.kube.Kube"));
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
I hope everyone understands what is my intension. In a simple way, I want to run a 3D application in such a way that, it should only render on top of every application in a translucent manner, at the same time, the user should be able to use his\her device in a normal way.
I think this is achievable as I have seen one third party 3D graphics application that runs absolutely fine the way I have described. Once launched, The application just runs on top of UI and doesn't intervene any user interaction. No tweaking of OS, no modification to any other application code.
Solution
Finally, figured out how to make it work. Somehow its working for me. The 3D Rubik cube is running fine all over the place :) . OK.. Lets get to the point...
Most of the changes I made is in "Kube.java" file. The Original Kube class used to extend activity. Now it actually extends service. Now it is KubeService. For this we need to provide body for two functions onBind() and onDistroy().
public IBinder onBind(Intent intent)
{
return null;
}
public void onDestroy()
{
super.onDestroy();
if (mView != null)
{
((WindowManager)getSystemService("window")).removeView(mView);
mView = null;
}
Log.v(TAG, "service stopped.");
}
Where does the window came from? Where we added our view to the window? Now this is the whole trick of making it work..
We need to rewrite the onCreate() method. Here is the onCreate() method that worked for me.
public void onCreate()
{
Log.v(TAG, "onCreate");
super.onCreate();
GLWorld myGLWorld = makeGLWorld();
mView = new GLSurfaceView(this);
mRenderer = new KubeRenderer(myGLWorld, this);
mView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
mView.setRenderer(this.mRenderer);
mView.getHolder().setFormat(PixelFormat.TRANSLUCENT); //many alpha bits
//mView.getHolder().setFormat(PixelFormat.TRANSPARENT); // at least 1 alpha bit
//mView.getHolder().setFormat(PixelFormat.RGBA_8888);
WindowManager localWM = (WindowManager)getBaseContext().getSystemService("window");
WindowManager.LayoutParams localLP = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT);
localLP.setTitle("KubeService");
localWM.addView(mView, localLP);
Log.v(TAG, "service started.");
}
Apart from these changes, don't forget to add SYSTEM_ALERT_WINDOW permission and kube.KubeService service as shown below in the Manifest file.
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<service android:enabled="true"
android:name=".kube.KubeService">
</service>
Now, everything is setup and we just need to create an intent for KubeService and start the service.
Intent kubeIntent = new Intent().setClassName("PACKAGE_NAME", "PACKAGE_NAME.kube.KubeService");
And
startService(kubeIntent);
Answered By - InvisiblePoint
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.