Open transparent activity and take a screenshot - android

I want to take a screenshot of the current screen of the device (without rooting). So I am opening a transparent activity to take a screenshot so that I can get the screenshot of the current device screen. But I am getting error as mentioned below.
P.S: I am able to get the screenshot image if I put the takeScreen() method inside the MainActivity class. But I don't want that.
MainActivity.java
public class MainActivity extends Activity {
Bitmap bitmap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
}
public void btn_1(View view) {
Intent mainIntent = new Intent(this, transparentActivity.class);
startActivity(mainIntent);
}
}
transparentActivity.java
public class transparentActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.transparent_layout);
}
#Override
protected void onStart() {
super.onStart();
Bitmap image = takeScreen();
}
public Bitmap takeScreen() {
View v1 = getWindow().getDecorView().getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
return bitmap;
}
}
main_layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin" >
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/button1"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:layout_gravity="center_horizontal|center"
android:layout_marginStart="235dp"
android:layout_marginBottom="99dp"
android:onClick="btn_1"
android:text="Button 1" />
</RelativeLayout>
transparent_layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="match_parent">
</android.support.constraint.ConstraintLayout>
AndroidManifest.xml
<activity
android:name=".MainActivity"
android:exported="true"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".transparentActivity"
android:exported="true"
android:theme="#android:style/Theme.Translucent.NoTitleBar" />
I am getting the below error when I am running the code.
java.lang.RuntimeException: Unable to start activity ComponentInfo{transparentActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference

Your approach will not take screenshot of the screen behind your transparent activity as this method only saves the content of the perticular view or layout not what you actually see on the screen.
So please try using Media Projection APIs - https://developer.android.com/reference/android/media/projection/package-summary as suggested in comments.
For error part, please click on the error message in the android studio - this will take cursor to the line where error is occurring and hopefully you can come to conclusion quickly.

You are getting that error because you are trying to get activity width and height before activity finish. You need to trigger it after activity is done, with an invisible button or something else.
By the way, you can't use life cycle to trigger your screenshot action because I already try it and give the same error like you. And as note even it can take screenshot the result will be black and I don't know why, but my thought is because activity it self even we can see it as transparent.

Related

android ( trying to use hdpi images for both phones and tabs ) but not working

I am trying to do a splash screen in android when have used (xxxhdpi) for tabs , but when i am using it in mobile phone the image is just stretching out so please help me out
There are a lot of things here. First of all, why do u want to keep only a single copy of the image you are talking about?
Its always better to have the images for all the respective densities, otherwise android will do the downscaling and upscaling on your images.
If apk size is a concern, you can look into density splits.
Now, back to your issue, it depends on the scaleType of your imageview. You can do something like this (in case you dont care about the dimentions of the image, otherwise you can set scaleType to fitXY):
<ImageView
...
android:scaleType="centerCrop"
...
</ImageView>
Now for loading the image into your imageview, I'll hghly recommend you use Picasso library.
In your activity, you can do something like this:
onCreate(...){
...
Picasso.with(mContext).load(R.drawable.my_splash_image).into(mMyImageView);
...
}
Let me know if this clears your doubts.
To solve your image stretching problem try:
<ImageView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:adjustViewBounds="true"/>
Also I suggest you to read Supporting Multiple Screens
try with this activity as your splash activity.
1.SplashActivity.java
public class SplashActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread timerThread = new Thread(){
public void run(){
try{
sleep(3000);
}catch(InterruptedException e){
e.printStackTrace();
}finally{
Intent intent = new Intent(SplashActivity.this,MainActivity.class);
TextView textView=(TextView)findViewById(R.id.textView1);
startActivity(intent);
}
}
};
timerThread.start();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
finish();
}}
2.make a layout like this
splash.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/splash_image"
android:orientation="vertical">
3.make sure that you manifest should launch the app main thread.like bellow
manifest.xml
<activity
android:name="com.example.brahmaiah.demo_proj_filpkart.SplashActivity"
android:label="#string/app_name"
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
`hope this will work fine for you.

How do i make multiple pages that i can go to in the app with buttons and make the imagebuttons link to these pages?

So this is my first app and I am trying to code and need some help with buttons. After searching for a answer I just couldn't find one that I understood. I want to be able to make different pages for the app and make imagebuttons that link to these pages. This is the very basic code I have at the minute for my button. Please try to explain where to put the code etc.
Thanks in advance.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageButton"
android:background="#drawable/home_button"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:nestedScrollingEnabled="true" />
</RelativeLayout>
Since this is your first app, let's start it simple with using only Activities.
You start with a MainActivity, which shall contain your ImageButtons. By clicking on one of these buttons, you will be directed to another activity. If you press the back button, you will arrive back at your MainActivity.
I shall demonstrate some code which shows you how to navigate from one activity to another one. First add the two activities so your AndroidManifest.xml will look something like this:
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SecondActivity"
android:label="#string/title_activity_second_activitity" >
</activity>
If you're using AndroidStudio, it will do this for you when you create a new activity.
Your MainActivity.java will look something like this:
public class MainActivity extends Activity {
//Define your views
private ImageButton imageButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Find your views
imageButton = (ImageButton) findViewById(R.id.image_button);
//Assign a listener to your button
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Start your second activity
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
});
}
}
Repeat these steps for every Activity you want to add to your application.
For more information, you will find the Android Docs an usefull source. Please check this link out as a start.
Good luck!
I dont think its a question to be questioned ! Though,make your desired button in your main .xml file and the using java access the button and apply the task which you want to perform from that button ..
You use this in .xml to make a button
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_text"
/>
Here's java code for accessing this button
private Button button;
public void addListenerOnButton() {
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
#Override public void onClick(View view) {
//do what you want here
}
});
}

Android: video returns to the beginning when device is rotated.

I have this activity that I use to play videos.
public class OtherActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
VideoView view = (VideoView) findViewById(R.id.videoView1);
view.setMediaController(new MediaController(this));
view.setVideoURI(Uri.parse("http:somevideo.mp4"));
}
}
And here is my layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<VideoView
android:id="#+id/videoView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"/>
</RelativeLayout>
Now, the problem here is that whenever I rotate the device the video goes back to the beginning. How can I stop this?
Your activity is simply restarting when it rotates. This is default behavior of Android.
Document yourself about android rotations and configChanges.
To make a device rotation a configuration change add the following code to the <activity> tag in the AndroidManifest.xml.
android:configChanges="orientation|screenSize"
Note: The device configuration is a set of characteristics that describe the current state of the device. The characteristics that make up the configuration include screen orientation, screen size, language and others.
I think this will be happened on activity restart.
Please add below line in activity tag of AndroidMainfest.
<activity
android:name="com.test.MainActivity"
android:configChanges="orientation|screenSize">
..........
..........
</activity>

String array or new class?

How my application works is once a user opens it, it will open to a screen where it will find out depending on the button the user clicks, how many holes of golf they want to play (18 or 9.) From there it will launch the main activity where, depending on what the user chose, will depend on the rules of the application. ie - If they choose 18, the save button wont activate until the 18th hole, same for 9, it will activate on the 9th hole. This will also trigger a final score notification, etc.
Im curious if I should create a separate class for 9 holes and 18 holes, or if I should just pass some sort of value from the open screen, to the main activity that sets the values at 9 or 18?
I guess I am curious on this programming etiquette as I am not very familiar with the best practice of something like this.
Entry screen will look something like this as of now (I have not finished 9 hole button or help button but will be the same as 18 unless launching a seperate class)
case R.id.button18Holes:
//*********************************//
//***LAUNCHES ACTUAL APPLICATION***//
//*********************************//
Intent myIntent = new Intent(src.getContext(), EasyPar.class);
startActivityForResult(myIntent, 0);
Intent iStartValues = new Intent(this, EasyPar.class);
String[] startValues = new String[] {"18"};
iStartValues.putExtra("strings", startValues);
startActivity(iStartValues);
break;
case R.id.button9Holes:
break;
case R.id.buttonHelp:
break;
}
Im not sure if that string array is the proper way to pass one to another activity either?
Thanks in advance!
Pure OO people would say you should create an abstract base class containing common operations and fields, and then for the specialisations, create sub classes. Case statements and if statements like you have above are not pure OO.
Same goes for arrays in general - in pure OO you might have them as a field in a class, but any operations performed on them would be inside a class.
Personally, I would say go with whatever you think will be easier to maintain, quicker to program and more obvious to other people reading the code. I guess that doesn't really answer the question though :-)
You should definitely not be using an array for only two objects! That is overkill. This is important because you have very little memory to work with on a mobile device and arrays eat up some memory. Also you should be using button listeners instead of switch/case statements to find what is going on.
First, I would highly suggest diving into OOP and learning the fundamentals of program using Java before diving right into Android. You do not have to go this route though, but I will say that if you choose to not learn the basics and fundamentals... prepare for a long hard road.
With that said, the simplest way to do this in Android IMHO is like this... The comments should provide you with enough insight to what is going on.
The Class files:
GolfTestActivity.class
package com.jmarstudios.golf;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class GolfTestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// This is the main xml layout: res/layout/main.xml
setContentView(R.layout.main);
}
#Override
protected void onStart() {
super.onStart();
// Get a handle to the two buttons in main.xml
final Button _nineHoles = (Button)this.findViewById(R.id.button1);
final Button _eighteenHoles = (Button)this.findViewById(R.id.button2);
// Create a listener for button1
_nineHoles.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Start the nine hole activity
GolfTestActivity.this.startActivity(new Intent().setClassName("com.jmarstudios.golf", "com.jmarstudios.golf.NineHoleActivity"));
}
});
// Create a listener for button2
_eighteenHoles.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Start the eighteen hole activity
GolfTestActivity.this.startActivity(new Intent().setClassName("com.jmarstudios.golf", "com.jmarstudios.golf.EighteenHoleActivity"));
}
});
}
}
NineHoleActivity.class
/**
*
*/
package com.jmarstudios.golf;
import android.app.Activity;
import android.os.Bundle;
/**
* #author DDoSAttack
*
*/
public class NineHoleActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// We simply inflate the layout: res/layout/nineholeslayout.xml
setContentView(R.layout.nineholeslayout);
}
}
EighteenHoleActivity.class
/**
*
*/
package com.jmarstudios.golf;
import android.app.Activity;
import android.os.Bundle;
/**
* #author DDoSAttack
*
*/
public class EighteenHoleActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// We simply inflate the layout: res/layout/eighteenholeslayout.xml
setContentView(R.layout.eighteenholeslayout);
}
}
and in the XML files...
res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Do you want 9 holes or 18 holes?" />
<Button
android:text="Nine Holes"
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:text="Eighteen Holes"
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
res/layout/nineholeslayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Nine Holes"
/>
</LinearLayout>
res/layout/eighteenholeslayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Eighteen Holes"
/>
</LinearLayout>
Finally you need to add the activities to your AndroidManifest.xml file
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jmarstudios.golf"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".GolfTestActivity" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".NineHoleActivity"></activity>
<activity android:name=".EighteenHoleActivity"></activity>
</application>
</manifest>
Here are some handy references that I HIGHLY recommend:
http://developer.android.com/reference/packages.html
http://developer.android.com/reference/android/app/Activity.html
http://developer.android.com/resources/faq/commontasks.html
Hope all that helps as this is pretty much a simple copy/paste thing

Android open new window problem

very easy question, i'm embarrassed to ask but cannot find it out on my own.
In MainActivity.java there is a menu. When user clicks on the menu item, a new window should appear but the app crashes ("the app stopped unexpectedly") instead.
MainActivity.java part:
case R.id.Menu6:
Intent intentabout = new Intent(this, About.class);
startActivity(intentabout);
break;
The case should be right, as the other menu items are working.
About.java:
public class About extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aboutxml);
TextView tv1 = (TextView)findViewById(R.id.TextView01);
tv1.setText("Something");
setContentView(tv1);
}
}
aboutxml.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="#+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:text="Something"
android:id="#+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
I have included the class in the AndroidManifest.xml:
<activity
android:name=".About"
android:label="#string/app_name">
</activity>
I can't believe i don't know this, i have other class in my app and they are working...
You shouldn't be calling setContentView twice. Remove the second call. That may or may not be your problem, but it needs to go. If that doesn't fix it, you need to post your error log. If you view it yourself, you'll probably figure it out pretty easily, but if not, post it here.

Categories

Resources