Home Tutorials Download Beta Store Forum Documentation KnowledgeBase Wiki Blog

ShiVa3D

Return to Getting Started

noob FAQ - Problem and Answers Only Pls

You feel lost? You don't understand how to use ShiVa?

Re: noob FAQ - Problem and Answers Only Pls

Postby gamescorpion » 02 Apr 2012, 11:21

ISSUE: How to take a screenshot and share it (Via email or other options) on WebOS?

OUR SOLUTION: Yep this took a long time to figure out (a good 5 hours) and then I kicked myself at how easy it is to do in WebOS and also this method could work for other platforms that have a difficult email attachment system.

1. Copy and paste this code into ShiVa in a HUD button and it should open a browser window in WebOS. At this point the user simply needs to click and hold on the image itself and it will allow them to share via email (And there you have it, sharing a screenshot from your app via email through WebOS):

NOTE: Replace YOUR_IMAGE_NAME.jpg with whatever you want (3 spots in code need to be changed to whatever image name you want).

Code: Select all
            cache.sendFile ( "YOUR_IMAGE_NAME.jpg", "file://"..system.getHomeDirectory ( ).."/Documents/YOUR_IMAGE_NAME.jpg" )   
            local sFileLocation = "file://"..system.getHomeDirectory ( ).."/Documents/YOUR_IMAGE_NAME.jpg"
            system.openURL ( " "..sFileLocation, "")         


Save and run the program. When a user clicks on your button, it will take a screenshot and open that screenshot in a browser window which the user can press and hold to get an option to share via email or other various share options :)

ENJOY!

Nav
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

Re: noob FAQ - Problem and Answers Only Pls

Postby gamescorpion » 02 Apr 2012, 11:27

ISSUE: How to send a basic simple email to a USER DEFINED EMAIL ADDRESS in WebOS?

OUR SOLUTION: This one is a bit tricky, well not really, it just took us time to figure out and when I realized it was a simple space that threw off everything I was reminded of the days of C++ and semi-colons and spending hours to find a single semi-colon missing GRRRRR lol.

Ok so here is the code, MAKE SURE THAT YOUR mailto: link has a SPACE infront of it or it will NOT load the email application!

PASTE THIS CODE INTO A BUTTON IN WHICH YOU WISH TO INITIATE AN EMAIL FROM:
Code: Select all
            system.openURL ( " mailto: test@test.com", "")         



This will open a new email window which will allow you to send a message to test@test.com. You can easily change this to any email entered by a user by editing the string. For example:

Code: Select all
            local sEmail = "test@test.com"
            system.openURL ( " mailto: "..sEmail, "")         


ENJOY!

Nav
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

Re: noob FAQ - Problem and Answers Only Pls

Postby RedQueen » 02 Apr 2012, 14:54

I don't know if anyone told you but MUCH APPRECIATION for the continued documentation of vital information. Thanks :D
RedQueen
Platinum Boarder
Platinum Boarder
 
Posts: 328

Re: noob FAQ - Problem and Answers Only Pls

Postby gamescorpion » 02 Apr 2012, 16:30

RedQueen wrote:I don't know if anyone told you but MUCH APPRECIATION for the continued documentation of vital information. Thanks :D


Thanks RedQueen :) Very grateful for the kind words.

God Bless!

Nav
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

Re: noob FAQ - Problem and Answers Only Pls

Postby gamescorpion » 07 Apr 2012, 23:10

ISSUE: How to send an image screenshot via Email (And potentially Facebook/Twitter)(ANDROID SPECIFIC USING INTENTS - INTERMEDIATE/ADVANCED TOPIC)

OUR SOLUTION: Hey all! This is going to be a cool tutorial that lets the user (based on what apps are available on a users device) share an image screenshot via their CHOICE OF APP! THIS TUTORIAL IS FOR ANDROID SPECIFICALLY! What will happen is upon clicking a button in your app, a screenshot will be taken and then a window will popup on the users device showing all the options available (Such as, "Would you like to share this image via: Facebook, Email, Twitter, etc.")

We will be drawing on the tutorial I made previously on Hooks and Callbacks specifically: http://www.stonetrip.com/developer/forum/viewtopic.php?f=27&t=23714&start=45#p44506

ASSUMPTION: We are going to assume that you have understood Hooks and Callbacks FOR ANDROID based on the previous tutorial and will not be going into much detail on it other than just providing the code and functions which you can copy/paste over. If you are confused about hooks and callbacks, go and look at that tutorial and you will learn how Hooks and Callbacks for Android work.

QUICK OVERVIEW:
1. ShiVa Code (Intermediate Users)
2. ShiVa UAT
3. Eclipse Hooks and Callbacks (Please refer to previous tutorial)

ShiVa Code (Intermediate Users)

Assumptions: I'm assuming that some of the basic ShiVa things like creating a HUD button and image are already things you can do, so I wont go into detail on those points. Also I am assuming your main user AI is called "MainAI" and that you've already setup the basics to get a program working (Ex. Dragging user AI to Game Editor, creating a basic HUD, loading an instance of a HUD via onInit, etc.). As I said, this tutorial is for more Intermediate/Advanced ShiVa devs so if you dont know how to do the basic setup, please refer to the wiki or various other tutorials available at this time.

1. Ok lets create first a HUD item that holds some image just for testing. Lets call it lbl_testimage. Inside this image put any image you may have on file from your computer. (For this tutorial I'm assuming you know how to do this)

2. Create a HUD button and connect it via code using CopyTagToRegister and SendEventToUser (Once again I'm assuming you know how to do this)

3. Inside the button code put the following:

Code: Select all
application.saveCurrentUserViewportToTexture ( "email.jpg", 1024, 600 )
cache.sendFile ( "email.jpg", "file://"..system.getHomeDirectory ( ).."/Documents/email.jpg" )   
local sFileLocation = "file://"..system.getHomeDirectory ( ).."/Documents/email.jpg"
user.sendEvent ( this.getUser ( ), "MainAI", "onSendScreenshot", sFileLocation )
log.message ( " Button Pressed " )


4. Create an empty handler called onSendScreenshot which takes in a STRING argument. This will have no code in it but will be used when we go to eclipse as a hook. It should look like this:

Code: Select all
--------------------------------------------------------------------------------
--  Handler.......... : onSendScreenshot
--  Author........... :
--  Description...... :
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
function MainAI.onSendScreenshot ( sFileLocation )
--------------------------------------------------------------------------------
   
   --
   -- Write your code here, using 'this' as current AI instance.
   --
   
--------------------------------------------------------------------------------
end
--------------------------------------------------------------------------------



5. If you save and run the program you should see in your log reporter "Button Pressed" whenever you click on the HUD button you made. If you do, then all is well so now please EXPORT your program as an STK file from the Game Editor and we will move onto the next step which is the UAT.

ShiVa UAT

1. Select Android as your target

2. Do all the basic setup for step 1 (icons, stk file, etc.)

3. In Step 2 select Project instead of APK file and then enter the rest of the details in.

4. In Step 3 select Development and select the options you need (such as Network, etc.). We will be exporting to C: to make all things easy. You can however export it to whatever folder you wish, just make sure there are NO spaces in the location (ex. "C:\Users\My Name Is Game Scorpion Inc\My Documents" is bad because there are spaces in the folder names. Android will fail when building if you have spaces. To keep it simple for that reason I work directly in the C:) Also I am assuming that you have already read the hooks/callbacks tutorial as you will need this for this section.

5. Once completed, hit build and you should have a Zip file built for you and placed in the folder location (In our example, C:)

Eclipse Hooks and Callbacks (Please refer to previous tutorial)

1. Open Eclipse and create a new Java file (New->Java Project)

2. Name your project and hit finish

3. Import the external files for the jni directory (As per the hooks/callbacks tutorial ANDROID VERSION)

4. In the C++ file create the following hook (Approx. line 660):

Code: Select all
      S3DClient_InstallCurrentUserEventHook ( "MainAI", "onSendScreenshot", onSendEmailImageCPP, NULL );      



and then the following callback function for onSendEmailImageCPP hook (approx. line 65) (NOTE: MAKE SURE TO EDIT THE LOCATION OF THE JAVA FILE IN THE FUNCTION BELOW!):

Code: Select all

   void onSendEmailImageCPP ( unsigned char _iArgumentCount, const void *_pArguments, void *_pUserData )
   {
      // Get input filelocation as a string
       if ( _pArguments && ( _iArgumentCount == 1 ) )
       {
           const S3DX::AIVariable *pVariables = (const S3DX::AIVariable *)_pArguments ;
       
           if ( pVariables[0].GetType ( ) == S3DX::AIVariable::eTypeString )
           {
               strncpy ( YOURSTRING, pVariables[0].GetStringValue ( ), 254 ) ;
           }
       }
   
        if ( pJavaVM )
        {
            JNIEnv *pEnv ;
            if    ( pJavaVM->GetEnv ( (void**) &pEnv, JNI_VERSION_1_4 ) >= 0 )
            {
                // EDIT THIS LINE TO POINT TO THE JAVA FILE LOCATED IN THE src FOLDER ON LEFT SIDE
                jclass pClass  = pEnv->FindClass ( "com/yourcompany/yourappnamealllowercase/YourAppNameCaseSensitive" );
                if   ( pClass != 0 )
                {
                   jmethodID pMethod = pEnv->GetStaticMethodID ( pClass, "onSendEmailWithImageJAVA", "(Ljava/lang/String;)I");
                  if      ( pMethod )
                   {
                     int dummy = pEnv->CallStaticIntMethod ( pClass, pMethod, pEnv->NewStringUTF ( YOURSTRING ) ) ;
                   }
                }
            }
        }
       
   }



And finally make sure we create the variable called YOURSTRING which is a 255 length string at the top of the CPP file (approx. line 46) before the static bool bVibrate global var:

Code: Select all
   static char        YOURSTRING [255]             = "" ;


And save the file.

5. Once you have setup your calls, go to your Java file and we will place the JAVA code. In the Java File before the function public void onLowMemory ( ) (approx. line 500) simply paste the following code:

Code: Select all
    public static int onSendEmailWithImageJAVA ( String sBody )
    {
       final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
       emailIntent.setType("image/jpg");
       emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse( sBody ) );
       oThis.startActivity(Intent.createChooser(emailIntent, "Share:"));

       return 0;
    }


Ok so the above code is the actual major code that calls android and tells it to bring up a chooser box. The chooser box displays a list of apps and programs available to share the selected image with. For example, the chooser may display EMAIL, Facebook, Twitter, Digg, etc. The user can then select what their preference is and use it. NOTE THAT NOT ALL APPS WILL FUNCTION WITH IMAGES CORRECTLY! Each app handles images differently IF AT ALL. So if its just plain text, you should be fine (Such as wanting to have a tweet sent or something). But if its an image, as is our case in this tutorial, each app MAY or MAY NOT accept an image so you will just end up having the other program open with an empty message.

6. Save the file and do an ANT build and compile and you should be able to test it out.

CONGRATULATIONS, you have now completed a successful image share! NOW IMAGINE WHAT OTHER NEAT THINGS YOU CAN DO! We will get to other neat things in the future, but for now this is the first major application which is sharing images from your app!

Nav
Last edited by gamescorpion on 12 May 2012, 23:38, edited 1 time in total.
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

Re: noob FAQ - Problem and Answers Only Pls

Postby gamescorpion » 07 Apr 2012, 23:32

ISSUE: How to take a screenshot and send it via WebOS and possibly other devices (THE EASY WAY WITHOUT USING HOOKS/CALLBACKS OR INTENTS)

OUR SOLUTION: Ok this is a very easy method that does not work for all devices, however it works for sure on WebOS (We tested it already and have it implemented in our Easter Egg app).

This is all ShiVa related code so you dont have to do anything but do everything in ShiVa :)

1. Create a button in a HUD in ShiVa

2. Write the following code into the button:

Code: Select all

application.saveCurrentUserViewportToTexture ( "email.jpg", 1024, 600 )
cache.sendFile ( "email.jpg", "file://"..system.getHomeDirectory ( ).."/Documents/email.jpg" )   
local sFileLocation = "file://"..system.getHomeDirectory ( ).."/Documents/email.jpg"

--WEBOS CODE BELOW, NOTE THAT THERE IS A SPACE AT THE BEGINNING BEFORE THE
--WORD FILE, IT IS REQUIRED!!!
system.openURL ( " file:"..system.getHomeDirectory ( ).."/Documents/email.jpg", "")         


NOTE: There is a SPACE before the word "file" in the openURL call. THIS SPACE MUST BE THERE FOR THE CALL TO WORK!

3. Compile and export and test it out on your device and it should open the screenshot in a browser window. If the user then simple presses and holds on the image a CHOOSER WINDOW will appear allowing them to share the screenshot via email, twitter, facebook, etc. depending on what is available on their device.

THE EASY WAY IS AWESOME WHEN IT WORKS! It can save you a lot of code time rather than doing hooks/callbacks however it does not work on all devices (We tested on iOS and Blackberry, just did not work, so really is dependent on the OS).

ENJOY!

Nav
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

Re: noob FAQ - Problem and Answers Only Pls

Postby gamescorpion » 09 Apr 2012, 20:15

ISSUE: ShiVa Crashed and now when I try to load it asks for activation key and even my ID computer ID has changed...WHAT HAPPENED?

OUR SOLUTION: Ok this is a very RARE thing that can happen (It happened to me personally) when your network has a power outage or some other network issue after you encounter a ShiVa crash. Your network settings get changed and thus your computer ID gets changed. This change pretty much makes your computer look like a totally different system so you need to go back to your user account on the Stonetrip website and re-assign your license to the new Computer ID that has been generated. This apparently (From what I was told by Stonetrip Tech Support) happens if your network had some weird outage or messed up during a config change on your router or some other way.

In any case here is the steps to fix:
1. Go to stonetrip and login to your account
2. Re-assign the license to your system again
3. Copy down the new activation code
4. Re-Activate and you're up and running again

Should you encounter any other issues while doing this, simply email the stonetrip staff. NOTE: It could take up to 24 hours for an email response depending on your time zone, but ShiVa staff are very prompt and fast. I encountered my issue at 12PM Eastern Time which is pretty much end of day for European countries so I believe they were closed and I had to wait until around 4-5am Eastern Time the next day for a response. Its fine, YOU NEED A BREAK ANYWAYS! lol

Nav
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

Re: noob FAQ - Problem and Answers Only Pls

Postby giggsy » 11 Apr 2012, 08:23

Thanks for sharing the code!
Question: have your tried "file://" or "file:///" instead of " file:"?

Edit: talking about
Code: Select all
system.openURL ( " file:"..system.getHomeDirectory ( ).."/Documents/email.jpg", "")         
User avatar
giggsy
Platinum Boarder
Platinum Boarder
 
Posts: 1105
Location: Austria

Re: noob FAQ - Problem and Answers Only Pls

Postby gamescorpion » 11 Apr 2012, 08:26

giggsy wrote:Thanks for sharing the code!
Question: have your tried "file://" or "file:///" instead of " file:"?

Edit: talking about
Code: Select all
system.openURL ( " file:"..system.getHomeDirectory ( ).."/Documents/email.jpg", "")         


Hi giggsy,

Yes, depending on device it works differently. Some will pick it up, some will not. Its very weird how it functions, but every devices is different with it. I tried the variations for Blackberry Playbook however the playbook denied me. I have yet to try on an android device. On iOS it did not work either, but worked well on WebOS.

Really device dependent and requires testing on the actual unit.

Hope that helps :)

Nav
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

Re: noob FAQ - Problem and Answers Only Pls

Postby gamescorpion » 18 Apr 2012, 08:53

ISSUE: How to track errors/bugs on actual device when I can't access log files?

OUR SOLUTION: We built our own function (Which I have placed in the Copy/Paste Functions section of which I have attached the link) that will allow you to log via HUD.

Right now you can use WITHIN ShiVa a regular log.message ( sText ) function to see log messages in the log viewer, however with our function you can also have a log message displayed on the screen as long as you have a HUD created in your app.

HUDLog Code:
http://www.stonetrip.com/developer/forum/viewtopic.php?f=40&t=24158&p=45141#p45141

This is very useful for testing on a device as you can then simply do the following call and on your screen you will see a log message for 5 seconds:

Code: Select all
this.HUDLog ( sText )


and you will see the message or text on the screen rather than just in the log. VERY useful for testing on actual devices.

NOTE: YOU MUST SETUP THE HUDLog function via the link provided above or else the code wont work as ShiVa does not come with this function (From what I know as of right now).

Nav
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

Re: noob FAQ - Problem and Answers Only Pls

Postby gamescorpion » 13 May 2012, 00:10

ISSUE: Quick or fast method to recompile app without having to redo all the work I have done in iOS / Eclipse?

OUR SOLUTION: As many of you start programming over and over in various platforms (Specifically iOS and Android (Eclipse) ) you will notice that you will be going back and forth between ShiVa and then ShiVa UAT then back to either iOS or Eclipse for the final code. Now the issue comes up when you do all the work to get CUSTOM code or even basic settings that may take you 20 min to setup inside Eclipse or xCode and having to REDO all of those settings again JUST for some simple changes in ShiVa for a bug you might have found.

DONT DESTROY ALL YOUR HARD WORK! These methods will allow you to save that re-code time (Yes I use to do this, such a n00b moment) and focus on editing those bugs without having to rewrite hooks/callbacks or even just basic settings such as setting up a Universal App in iOS.

NOTE: When we first learned this, we saved ourselves HOURS of code time!

ASSUMPTION: We are assuming that you have ALREADY setup and created the code in xCode or Eclipse and are just simply trying to replace your ShiVa changes. If you are starting from scratch then this is not for you.

iOS (xCode):

1. After you Export from ShiVa simply copy the stk file to your Mac (Assuming you are working on PC) inside the RESOURCES folder of your project (ex. APP_NAME.s3dxproj/Resources)

2. Inside the Resources folder there should be a file called S3DMain.stk. DELETE IT and then RENAME the file you just copied over to S3DMain.stk.

3. In xCode simply hit clean and rebuild and then run and you should be up and running without any issues :) ENJOY THE TIME SAVING!


Android (Eclipse):

1. After you export from ShiVa Go into UAT
2. In UAT Setup for Eclipse Output (Step 2: Authoring set to Project, Step 3: Build set to Development)
3. After exporting the file (A ZIP FILE), unzip it and you should see a folder called ASSETS
4. Copy the S3DMain.smf file from the UNZIPPED folder to your ASSETS folder in the workspace of the project you are working on in Eclipse
5. Rebuild and enjoy saving yourself LOTS OF TIME in having to re-code your hooks/callbacks and all the setup, just because you wanted to change code in ShiVa :)


God Bless!

Nav
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

Re: noob FAQ - Problem and Answers Only Pls

Postby redmotion » 13 May 2012, 09:35

Thanks for the tip. I've been doing this for Android (to add Leadbolt and a nicer app icon) but it's nice to know iOS allows something similar. I only got ios development up and running last weekend.
User avatar
redmotion
Platinum Boarder
Platinum Boarder
 
Posts: 574

Re: noob FAQ - Problem and Answers Only Pls

Postby gamescorpion » 14 May 2012, 06:48

ISSUE: How to (ANDROID VERSION) dim the screen in your app?

OUR SOLUTION: This solution took me 16 hours to figure out as there is no official way to do this correctly. For our app, iClock Station Pro we required a built in Dimming button that allows a user to dim the screen. To do this we required Hooks and Callbacks and specific Java code for Android.

NOTE: There is however an issue and that is that your app will be RESTARTED in order for the dimming to take place. This dimming is only within your app and after a user exits your app the system should put the settings back, however this is dependent on each device. For this reason I recommend you put exit/recovery code into the onDimTouch handler you will be creating below to help reload the app in the same spot again after the app restarts.

REFERENCE CODE: Learn Hooks and Callbacks here in this tutorial -> http://www.stonetrip.com/developer/forum/viewtopic.php?f=27&t=23714&start=45#p44506

Stack Overflow Reference -> http://stackoverflow.com/questions/6708692/changing-the-screen-brightness-system-setting-android

TUTORIAL BREAKDOWN:
1. ShiVa Code (Create a button that links to this)
2. ShiVa UAT
3. Eclipse Hook and Callback
4. Actual Java Code
5. Bright.java Class
6. AndroidManifest.xml

1. ShiVa Code

1. In ShiVa create a button in your HUD which we will use for Dimming and connect it to yor code. (In this tutorial we assume you know how to do this)

2. Create a new handler called onDimTouch()

3. Connect your button to the Handler using the following code (Assuming your main ai is MainAI and your HUD is called unique_instance_main_hud and your button is called btn_dimtouch):

Code: Select all
    -- Assuming your HUD is called unique_instance_main_hud and button is btn_dimtouch
    if ( sTag == "unique_instance_main_hud.btn_dimtouch" ) then   
   -- Assuming your main ai is called MainAI     
        user.postEvent ( this.getUser ( ), 0, "MainAI", "onDimTouch" )
    end



4. Export your stk file and move onto the next step.

2. ShiVa UAT

1. In ShiVa UAT ANDROID SECTION setup all step 1 items such as the STK we just created followed by the icon and launch image.

2. In Step 2: Authoring set the Authoring Type to Project

3. In Step 3: Build set the Build Type to Development and the output to C:

4. Click Build and you should have a Zip file created.

5. Go to the first REFERENCE: http://www.stonetrip.com/developer/forum/viewtopic.php?f=27&t=23714&start=45#p44506

and complete step 4 (ECLIPSE STEPS) and step 5 (C++ and JAVA Hook/Callback).

6. Move onto MAIN STEP 3 (Eclipse Hook and Callback) after completing the above steps.

3. Eclipse Hook and Callback

ASSUMING AT THIS POINT ECLIPSE IS OPEN AND YOU ARE NOW GOING TO START WORKING IN THE C++ FILE.

1. At approximately line 12 after the first #include, add the following include:

Code: Select all
#include "S3DXAIVariable.h"


2. At approximately line 630 after "// @@BEGIN_JNI_INSTALL_EVENT_HOOKS@@" add the following HOOK code below it:


Code: Select all
      S3DClient_InstallCurrentUserEventHook ( "MainAI", "onDimTouch", fun_CallCPPDimTouch, NULL ); 



3. At approximately line 64 after "// @@BEGIN_JNI_CALLBACKS@@" add the following CALLBACK function code (MAKE SURE TO EDIT THE CORRECT LINE FOR PACKAGE NAME IN THE CODE (ex. com/company/app/App):

Code: Select all

       void fun_CallCPPDimTouch ( unsigned char _iArgumentCount, const void *_pArguments, void *_pUserData )
       {
       
            if ( pJavaVM )
            {
                JNIEnv *pEnv ;
                if    ( pJavaVM->GetEnv ( (void**) &pEnv, JNI_VERSION_1_4 ) >= 0 )
                {
                    //EDIT BELOW FOR YOUR PACKAGE NAME ex. com/company/app/App
                    jclass pClass  = pEnv->FindClass ( "com/gamescorpion/iclockstationpro/iClockStationPro" );
                    if   ( pClass != 0 )
                    {
                       jmethodID pMethod = pEnv->GetStaticMethodID ( pClass, "CallJAVADimTouch", "()I");
                      if      ( pMethod )
                       {
                         int dummy = pEnv->CallStaticIntMethod ( pClass, pMethod ) ;
                       }
                    }
                }
            }
           
       }



4. Save and close the file and move onto the JAVA FILE

4. Actual Java Code (JAVA FILE)

THIS PART HAPPENS IN THE JAVA FILE

1. Go down to approx. line 500 and before the "public void onLowMemory ( )" function paste the following function in:


Code: Select all
    public static int CallJAVADimTouch( )
    {
       // JAVA CODE HERE
       int nBrightness = 255;
       try {
         nBrightness = android.provider.Settings.System.getInt(oThis.getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS );
      } catch (SettingNotFoundException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }       
       int brightness = 128; // THIS IS WHERE YOU SET YOUR DIMMING BRIGHTNESS. CAN BE BETWEEN 0-255
        android.provider.Settings.System.putInt(oThis.getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS, brightness);
       Intent intent = new Intent(oThis.getBaseContext(), Bright.class);
       intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //this is important
       //in the next line 'brightness' should be a float number between 0.0 and 1.0
       intent.putExtra("brightness value", 0.5f);
       oThis.getApplication().startActivity(intent);

       return 0;
    }


NOTE: This is specifically where you can set your brightness of the dimming of the screen between 0 to 255. YOU MAY ALSO use the OBTAINED nBrightness to know what the current brightness is set to.

2. Now we must create a new class called Bright. Move onto the next step after Saving and Closing the JAVA file.

5. Bright.java Class

1. In Eclipse Package Explorer click on the arrow under the "src" folder.

2. Right click on the package name that appears (ex. com.companyname.appname) and select New->Class

3. Type in the name "Bright" and hit Finish.

4. Replace the entire code (CTRL+A and then Delete to delete all the code) with the code below and make sure to change the package name to your app name (ex. com.companyname.appname) in the FIRST LINE:

Code: Select all
package com.gamescorpion.iclockstationpro;

//CHANGE LINE ABOVE ^ to com.companyname.appname

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.WindowManager;


public class Bright extends Activity {
    private static final int DELAYED_MESSAGE = 1;

    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);           
        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                if(msg.what == DELAYED_MESSAGE) {
                    Bright.this.finish();
                }
                super.handleMessage(msg);
            }
        };
        Intent brightnessIntent = this.getIntent();
        float brightness = brightnessIntent.getFloatExtra("brightness value", 0);
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.screenBrightness = brightness;
        getWindow().setAttributes(lp);

        Message message = handler.obtainMessage(DELAYED_MESSAGE);
        //this next line is very important, you need to finish your activity with slight delay
        handler.sendMessageDelayed(message,1000);
    }
}

5. Save file and then close and move onto next step (AndroidManifest.xml)



6. AndroidManifest.xml

1. In Eclipse Package Explorer Double Click on AndroidManifest.xml

2. At approx. line 17 after the end tag </activity> paste the following code and make sure you change the package name to your app package ending it with "Bright" (ex. com.company.appname.Bright) in the first LINE for android:name :

Code: Select all
      <activity android:name="com.gamescorpion.iclockstationpro.Bright"
               android:taskAffinity="com.dummy.dummy.Dummy"
               android:excludeFromRecents="true">
      </activity>       


NOTE: If you need full explanation on why we are using the above code, please refer to the helper website that gave me the solution: http://stackoverflow.com/questions/6708692/changing-the-screen-brightness-system-setting-android

3. At approx. line 27 after <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> PASTE THE FOLLOWING CODE:

Code: Select all
   <uses-permission android:name="android.permission.WRITE_SETTINGS"/>


4. Save your manifest file and then COMPILE AND TEST

====================

CONGRATULATIONS, you have now achieved screen dimming to save on power for Android Devices. From here you can customize the Java code and your own code as you like (if you read over the hooks/callbacks tutorial) you can even make it customizable dimming from your app by passing an integer variable right into the Java function. Its really up to you how you use the functionality, but remember that your app will restart each time to have the changes take effect.

This is the method that works as many others out there are just running around in circles and/or are just confusing and most importantly are not even related to a ShiVa Pipeline. I have personally tested the result on a Kindle Fire and Barnes and Noble Nook Color (TM).

Enjoy and God Bless!

Nav
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

Re: noob FAQ - Problem and Answers Only Pls

Postby gamescorpion » 19 May 2012, 09:48

3 New INTERMEDIATE/ADVANCED tutorials are in the works right now for the following (Just in case someone was wondering what's to come):

1. Android NOTIFICATIONS: This tutorial will teach you how to send notifications that a user will receive in their notification list on their android device. This is great if you wanted to send a little message like a game achievement hit or even a friendly reminder from your game. There are a LOT of applications for this functionality. We used it to send a message that one of the clock alarms (iClock Station Pro) had been hit.

2. Android TURN ON FROM SLEEP: This tutorial will teach you how to TURN ON an android device from sleep (Wake Device Up) at a certain timed interval. You can then use tutorial 3 in combination with this or even the first tutorial above in combination to display a notification or load your app up. In our case we used this to wake the device up at the ALARM time which is very useful.

3. Android RUN AN APP AT A PREDEFINED TIME: This tutorial will teach you how to run a specific application from android at a predefined time. NOTE: Your app must at least be running in the background for this functionality to work. We basically combined this with tutorial 2 above to allow it so that when an alarm in iClock Station Pro was hit, the device would turn on from sleep and play the alarm by running our program OR would turn the program on specifically overtaking any other program just so that an alarm can be played. Example usage in iClock Station Pro: User sets alarm for 30 minutes to read an eBook. In 30 minutes iClock Station Pro opens up above the eBook app and starts playing alarm. Example 2: User sets alarm in iClock Station Pro for 8 hours from now to wake up and then turns device to sleep mode (Hitting the power button to be in sleep, not fully turning device off). The device will then wake up after 8 hours, turn on the app, and then iClock Station Pro will play the alarm noise.

I AM WORKING ON ALL 3 TUTORIALS or I may just mix two of them together, but very useful tutorials for those who are looking to add any of these functionalities in. TO PREPARE, go and read up on Event Hooks and Callbacks for android in this same noob FAQ so that you are prepared when I bring out the tutorials.

ENJOY and God Bless!

Nav
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

Re: noob FAQ - Problem and Answers Only Pls

Postby gamescorpion » 20 May 2012, 08:04

3 Intermediate and Advanced Android Tutorials:

RESOURCES:

http://smartandroidians.blogspot.ca/2010/04/alarmmanager-and-notification-in.html

http://www.anddev.org/other-coding-problems-f5/acquire-causes-wakeup-not-working-on-some-devices-t48434.html

http://stackoverflow.com/questions/9631869/light-up-screen-when-notification-received-android

http://forum.xda-developers.com/showthread.php?t=1134978

http://stackoverflow.com/questions/2780102/open-another-application-from-your-own-intent

http://www.stonetrip.com/developer/forum/viewtopic.php?f=27&t=23714&start=45#p44506

TUTORIAL 1: INTERMEDIATE Android Programming Intents and PendingIntents

ISSUE: How to do something in Android at a SPECIFIC time?

OUR SOLUTION: This is a series of tutorials that will build on each other. We will first start with Intents and PendingIntents.

First, you will need to review the Hooks and Callbacks tutorial. I will assume for this tutorial that you know how to setup a function call in ShiVa and then send data and information through to a Hook/Callback function and right into Java code. I will only be sharing in these tutorials the JAVA CODE part of it, so you need to first complete the Hooks and Callbacks tutorial first until you reach the JAVA file section. http://www.stonetrip.com/developer/forum/viewtopic.php?f=27&t=23714&start=45#p44506

1. What is an INTENT?

This is a specific command in Android that allows you to send a command to the Android OS to do something specific. Think of it like an action that needs to take place. There are many actions that can be done such as sending an email, or attaching a photo to an email or even launching an application.

The logical workflow of creating an intent is usually as follows:

a. Create the Intent
b. Add Intent options -> Ex. what type of intent we are sending to the OS or any attributes associated with that intent (Such as a text string or something being passed along with the intent)
c. RUN the Intent

Real Life Example: Lets say I wake up in the morning and I "INTEND" to go to the washroom. I will first have to THINK about going to the washroom, but that DOESNT really get me to the washroom. I will then have to tell my brain to get out of bed first, then walk to the washroom, and then release, then go and wash my hands, then go and wipe my hands. Once I know where I'm going I SEND the command to begin and my body takes action.

2. What is a PENDING INTENT?

Continuing from the real life example, lets say now I want to take a shower but I want to shower AFTER I brush my teeth and eat breakfast so I know I wont be showering until at least 30-40 minutes. I still setup in my head that I need to prepare my clothes, and then walk up the stairs back to the bathroom, then undress and then shower. However this will not happen until 30-40 minutes passes. I now have a PENDING intent to shower. It is PENDING for 30-40 minutes, and so I do not take action on it until 30-40 minutes passes.

That is pretty much the difference between a Pending Intent and a Regular Intent. Regular Intents can be created without a Pending Intent, however in order to create a Pending Intent you need to have a Regular Intent setup first.

SO ->

Regular Intent -> DOES NOT REQUIRE PENDING INTENT TO BE MADE
Pending Intent -> REQUIRES A REGULAR INTENT TO BE CREATED

===============

Ok so now that we have some of the theory out of the way (btw if you want a more "TEXTBOOK" definition, just google Intents and Pending Intents) lets work on the actual code.

TUTORIAL 2: Create a NOTIFICATION at a specific time in Android and FORCE screen on if it is not on.

ISSUE: How to create a Notification to be sent to user at a specific time in Android?

OUR SOLUTION:

NOTE: This solution will only set a notification in the notification bar WHEN the user is OUTSIDE of your app. Thats the point of notifications, to tell the user something when they are NOT inside of your app. It will NOT send a notification while INSIDE your app (however I'm sure there's a way to do this functionality if you wanted it specifically). So to TEST the code, you need to exit out of your app in order to see the notification pop up. Its better to set a PREDEFINED TIME in the future for the notification to pop up, for example we have it set to 300 seconds, however you can set the notification to pop up whenever you want just by editing the JAVA CODE for nSeconds.

NOTE 2: This code will FORCE the Android device to wake up from sleep mode as well. The user will then have to unlock their keyboard or phone in order to see the notification.

1. First create a function in ShiVa to send a notification (TEXT) through a function. Something like "onCreateNotification ( sText )"

2. Complete the entire Hooks and Callbacks tutorial with this new function only and go all the way until you reach the JAVA file section. We are assuming you called the JAVA function "CallJAVANotification" (you will require to pass a STRING so make sure you pass a string through in the C++ portion of the code). NOTE: If you are truely having trouble with this just ask and I would be happy to help you through it. Hooks and Callbacks Tutorial -> http://www.stonetrip.com/developer/forum/viewtopic.php?f=27&t=23714&start=45#p44506

3. Copy and Paste this function below into the JAVA file at approx. line 505 before the "public void onLowMemory ( )" function:

Code: Select all

    public static int CallJAVANotification ( String sText )
    {
       // Create a new double variable called nSeconds.  THIS IS WHERE YOU EDIT HOW LONG BEFORE THE NOTIFICATION IS SHOWN TO THE USER.  We have set it here for 5 minutes (300 seconds), however you can set it to any time you want to.  Make sure you have exited the application in order to see the notification.
   double nSeconds = 300.0;
   
   // Create a new AlarmManager called am
       AlarmManager am;

   // Set am to ALARM_SERVICE
       am = (AlarmManager) oThis.getSystemService(Context.ALARM_SERVICE);

   // Create REGULAR INTENT based on the Alarm Receiver class
       Intent intent = new Intent(oThis.getBaseContext(), AlarmReceiver.class);

   // Pass along the string data with the intent
       intent.putExtra("sText", sText);

   // Create a PENDING INTENT which is based on the REGULAR INTENT above and make sure it happens ONLY ONCE
       PendingIntent pendingIntent = PendingIntent.getBroadcast(oThis.getBaseContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT);
   
   // Cancel ALL other previous PENDING INTENTS that were called using the same ID of 0 in this case
       am.cancel(pendingIntent);

   // Set the Alarm Manager to run the PENDING INTENT IMMEDIATELY as our nSeconds is set to 0. (In future we can set this to a specific time ahead)
       am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (long) (nSeconds * 1000), pendingIntent);

   // Return
       return 0;
    }



4. NEXT we need to create a BroadcastReceiver in a new Activity class. In your Package Explorer window in Eclipse, click on the arrow next to src and then right click on the pacakge folder (will look like: com.yourcompany.yourappname) and then click on New->Class.

5. Name the class "AlarmReceiver" without the quotes and hit the Finish button.

6. Now copy the code below into it and REPLACE the first line (package com.yourcompany.yourappname) with your own package name:

Code: Select all

// REPLACE LINE BELOW
package com.yourcompany.yourappname;

import android.app.Activity;
import android.app.KeyguardManager;
import android.app.KeyguardManager.KeyguardLock;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.view.Window;
import android.view.WindowManager;

public class AlarmReceiver extends BroadcastReceiver {

   // Create a new Notification Manager called nm
   NotificationManager nm;

   // Create a new Power Manager called pm
   PowerManager pm;

   // Main function for activity
   @Override
   public void onReceive(Context context, Intent intent) {
             
      // Set pm to Power Service so that we can access the power options on device
      pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);

      // Set WHERE the notification is coming 'from' (You can place your app name here if you wish)
      CharSequence from = "YourAppNameHere";
   
      // Check if the screen itself is off or not. If it is then this code below will FORCEFULLY wake up the device even if it is put into sleep mode by user
      if(pm.isScreenOn() == false)
           {
         PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "MyLock");
              wl.acquire(10000);
              PowerManager.WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyCpuLock");
              wl_cpu.acquire(10000);
      }

      // Set the notification manager to Notification Service
      nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

      // Get the text we passed in from ShiVa and place that text here in the message we are going to display to user
      CharSequence message = intent.getCharSequenceExtra("sText");
   
      // Create a new pending intent called contentIntent
        PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), 0);

      // Create a new notification which will include YOUR APP ICON
        Notification notif = new Notification(R.drawable.app_icon, message, System.currentTimeMillis());

      // Setup the notification window
      notif.setLatestEventInfo(context, from, message, contentIntent);

      // This flag here will INSISTENTLY send the notification to the user until the user ACKNOWLEDGES the notification by clicking on it
        notif.flags = Notification.FLAG_INSISTENT;

      // This actually runs the notification command itself
        nm.notify(1, notif);
    
    }
   
}





7. Now save that file and open up the AndroidManifest.xml file by double clicking on AndroidManifest.xml in your Package Explorer window on the left.

8. Inside the AndroidManifest.xml file we need to tell our app that we are using a Broadcast Receiver and where to find the AlarmReceiver file. Right after the activity end tag on approx. line 17-18 paste the following code AND REPLACE THE PACKAGE INFO like this -> com.yourcompany.yourapp.AlarmReceiver :

Code: Select all
      <receiver android:name="com.yourcompany.yourapp.AlarmReceiver"/>


9. This next item to add into the AndroidManifest.xml file I believe is needed, but never really knew why, but in any case just add it in as this is what worked for me lol. In any case you MAY NOT need this step but just incase it wont hurt to add it in, you can remove it if you find it will work without it or if you dont want it.

Go to line approx. 25 or so right at the very end of the '<uses-permission>' tags and add the following code:

Code: Select all
   <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />


10. Save the file and compile and test, you should now see your notifications running.

TUTORIAL 3: How to run an app from code

1. Finish tutorial 2 above so that you now have an "AlarmReceiver.java" class file

2. Open the AlarmReceiver.java file and at approx. line 50 under the 'nm.notify(1, notif);' line add the following code:

Code: Select all
   // Create a new intent based on the MAIN ACTION
   Intent i = new Intent(Intent.ACTION_MAIN);

   // Create a new Package Manager called manager   
   PackageManager manager = context.getPackageManager();
   
   // Set the intent to launch the package of the name com.appcompany.appyouwanttolaunch <- REPLACE THAT WITH THE APP PACKAGE YOU WANT TO LAUNCH
   i = manager.getLaunchIntentForPackage("com.appcompany.appyouwanttolaunch");
   
   // Set the intent category to launcher to be able to launch an app
   i.addCategory(Intent.CATEGORY_LAUNCHER);

   // Send the command to start the intent
   context.startActivity(i);



3. Now you should be able to launch apps right from Android code, congratulations!

COMPLETED CODE BELOW FOR AlarmReceiver.java:

Code: Select all

// REPLACE LINE BELOW
package com.yourcompany.yourappname;

import android.app.Activity;
import android.app.KeyguardManager;
import android.app.KeyguardManager.KeyguardLock;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.view.Window;
import android.view.WindowManager;

public class AlarmReceiver extends BroadcastReceiver {

   // Create a new Notification Manager called nm
   NotificationManager nm;

   // Create a new Power Manager called pm
   PowerManager pm;

   // Main function for activity
   @Override
   public void onReceive(Context context, Intent intent) {
             
      // Set pm to Power Service so that we can access the power options on device
      pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);

      // Set WHERE the notification is coming 'from' (You can place your app name here if you wish)
      CharSequence from = "YourAppNameHere";
   
      // Check if the screen itself is off or not. If it is then this code below will FORCEFULLY wake up the device even if it is put into sleep mode by user
      if(pm.isScreenOn() == false)
           {
         PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "MyLock");
              wl.acquire(10000);
              PowerManager.WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyCpuLock");
              wl_cpu.acquire(10000);
      }

      // Set the notification manager to Notification Service
      nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

      // Get the text we passed in from ShiVa and place that text here in the message we are going to display to user
      CharSequence message = intent.getCharSequenceExtra("sText");
   
      // Create a new pending intent called contentIntent
        PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), 0);

      // Create a new notification which will include YOUR APP ICON
        Notification notif = new Notification(R.drawable.app_icon, message, System.currentTimeMillis());

      // Setup the notification window
      notif.setLatestEventInfo(context, from, message, contentIntent);

      // This flag here will INSISTENTLY send the notification to the user until the user ACKNOWLEDGES the notification by clicking on it
        notif.flags = Notification.FLAG_INSISTENT;

      // This actually runs the notification command itself
        nm.notify(1, notif);

      // Create a new intent based on the MAIN ACTION
      Intent i = new Intent(Intent.ACTION_MAIN);

      // Create a new Package Manager called manager   
      PackageManager manager = context.getPackageManager();
   
      // Set the intent to launch the package of the name com.appcompany.appyouwanttolaunch <- REPLACE THAT WITH THE APP PACKAGE YOU WANT TO LAUNCH
      i = manager.getLaunchIntentForPackage("com.appcompany.appyouwanttolaunch");
   
      // Set the intent category to launcher to be able to launch an app
      i.addCategory(Intent.CATEGORY_LAUNCHER);

      // Send the command to start the intent
      context.startActivity(i);
    
    }
   
}




==============


Hope you enjoyed the 3 tutorials!!

God Bless!

Nav
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

PreviousNext

Return to Getting Started