How to use is_single and get_post_type within a plugin?

You need to hook into an appropriate place within the WordPress load sequence.

For example,

add_action('init', 'my_function'); //is too early and won't work!

Where as,

add_action('wp', 'my_function'); //will work!

And so too will,

add_action('template_redirect', 'my_function'); //this works too!

In fact template_redirect fires just before rendering the page/post to the viewer so its an appropriate place to hook into to perform your action.

Take the following example, if it were placed within your plugin file, will successfully pass the is_single conditional check, then proceed to add a filter which replaces the_content with a completely custom result, in this case a simple string which outputs new content will be displayed in place of what is held in the database.

function plugin_function(){
    
    if(is_single()) {
    
        add_filter('the_content', 'filter_content');
        
        function filter_content(){
            echo 'new content';
        }
        
    }
    
}

add_action('template_redirect', 'plugin_function');

As an example, try changing the last line above to read,

add_action('init', 'plugin_function'); 

Using the init hook is to early, instead of seeing our filtered content as in the function above, you’ll notice the regular post content from the database is shown instead.

Hope this helps.

UPDATE

Since you mentioned in your comments you’re using a CLASS, are you using a constructor for your add_action/add_filter?

Example:

add_action( 'template_redirect', array( 'YourClassNmae', 'init' ) );

class YourClassNmae {

    public static function init() {
        $class = __CLASS__;
        new $class;
    }

    public function __construct() {
         //your actions/filters are to be added here... 
         add_filter('the_content', array( $this, 'filter_content') );
    }

         public function filter_content(){
             echo 'new content';
         }
     
}

Codex Reference: Using add_action with a class