startService from main activity not working (IntentService) - java

after been searching stackoverflow to see if there was a question to this, there none that helped me on this.
On my main activity I have this:
if (GlobalVars.espera == 0)
{
GlobalVars.espera = 1;
try
{
bgIntent = new Intent(this, Loadscreen.class);
startService(bgIntent);
}
catch (Exception e)
{
GlobalFunctions.toast_message(context, "nao");
}
}
When i start the application it should load the intend to work on background but it isn't.
Here is the class of loadscreen:
public class Loadscreen extends IntentService{
MainActivity teste;
private static final String intService = "loadscreen";
public Loadscreen()
{
super(intService);
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent)
{
teste = new MainActivity ();
try
{
teste.inic();
}
catch (Exception e)
{
}
}
}
and manifest I have put
<service android:name=".Loadscreen"></service>
on it too, as a child of application
Even that I have the try, it doesn't go into the catch AKA error, but still doesn't go into the class Loadscreen.
Thanks for the help and time

You have
teste = new MainActivity (); // assuming MainActivity is a Activity class
You are instantiating Activity class which is wrong.

Related

how to disable screenshot in capacitor plugin only for few pages not for entire app

it's an ionic capacitor angular project in which I am trying to build a capacitor plugin so that I can disable screenshots only for required pages/screens.
I have used getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); within MainActivity inside onCreate() method, it works but it disables the screenshot for entire application which is not the desired outcome.
MainAcitivity.java:
public class MainActivity extends BridgeActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
// Initializes the Bridge
this.init(savedInstanceState, new ArrayList<Class<? extends Plugin>>() {{
// Additional plugins you've installed go here
// Ex: add(TotallyAwesomePlugin.class);
add(Contacts.class);
add(Screenshot.class);
}});
}
}
Now I have capacitor plugin "screenshot-plugin" in which I have 2 methods to "SET" and "CLEAR" the flag for particular pages/screen in project.
Screenshot.java:
#NativePlugin
public class Screenshot extends Plugin {
#PluginMethod
public void echo(PluginCall call) {
String value = call.getString("value");
JSObject ret = new JSObject();
ret.put("value", value);
call.success(ret);
}
#PluginMethod
public void enableScreenshot(PluginCall call) {
try {
Activity activity = getBridge().getActivity();
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
} catch (Exception e) {
Log.e("ABC", "Exception in enableScreenshot", e);
}
JSObject ret = new JSObject();
ret.put("status", true);
call.success(ret);
}
#PluginMethod
public void disableScreenshot(PluginCall call) {
try {
Activity activity = getBridge().getActivity();
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
} catch (Exception e) {
Log.e("ABC", "Exception in disableScreenshot", e);
}
JSObject ret = new JSObject();
ret.put("status", true);
call.success(ret);
}
}
Here I get an exception that only thread which created the view can modify it.
So I tried using MainActivity activity = new MainActivity() so that I can call getWindow() method on this activity but this gives an error cannot resolve symbol even when package is imported com.abc.myapp.
Also, when I try to use getWindow() without activity inside screenshot plugin then AndroidStudio gives compilation error, using getBridge().getActivity() and then calling getWindow() method (as in code) removes compilation error but gives above exception of only MainActivity can do so.
I could write these 2 methods in MainActivity itself but then not sure how to access these methods in ionic project component.
Using plugin I can call these methods inside my component but how to make this work for only few components/pages/screens and not for the entire android application.
Please help, Thanks in advance.
I know similar questions are already there but their use case and mine are different.
You can do like this in page where you want to disable:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE);
And remove flag from page where you don't want:
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
Note: Not 100% sure but may be it give some idea.
found the answer to this, I built my own capacitor plugin and it works fine, but there is another plugin that is already published in the capacitor community and it supports IOS too, so check this out https://github.com/capacitor-community/privacy-screen
for those of you who want to know how it worked successfully, you have to put your code like this:
#PluginMethod
public void enableScreenshot(PluginCall call) {
final Activity activity = getBridge().getActivity();
final JSObject ret = new JSObject();
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
try {
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
} catch (Exception e) {
Log.e("ABC", "Exception in enableScreenshot", e);
ret.put("status", false);
}
}
});
if (!ret.has("status")) {
ret.put("status", true);
} else {
call.reject("Exception in enableScreenshot");
}
call.success(ret);
}
#PluginMethod
public void disableScreenshot(PluginCall call) {
final Activity activity = getBridge().getActivity();
final JSObject ret = new JSObject();
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
try {
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
// Toast.makeText(activity, "Screenshot not allowed on this page.", Toast.LENGTH_SHORT);
} catch (Exception e) {
Log.e("ABC", "Exception in disableScreenshot", e);
ret.put("status", false);
}
}
});
if (!ret.has("status")) {
ret.put("status", true);
} else {
call.reject("Exception in enableScreenshot");
}
call.success(ret);
}
activity.runOnUiThread() is the hero.

How to access the clipboard on android device

My initial issue is being able to click a "PASTE" bubble that pops up when the a click is being held on a text field. Currently I have not found a way to get that action to happen using uiautomator script/code. So I started looking at directly accessing the clipboard. Now I am having issues accessing the clipboard on the android device. We are not using an app (apk), but are pushing a jar to the device and then using adb runtest to run the classes. So no activities are being started. I am guessing that is were all my issues are coming from. I have created a class file that I call trying to access the clipboard. But am currently getting this error message "java.lang.IllegalStateException: System services not available to Activities before onCreate()". I am new to android and uiautomator. Where/how do I add onCreate() to this code. I know the process we are using is odd at best. Any help at either getting the "PASTE" bubble clicked using uiautomator or getting the class to work would be appreciated.
I tried the onCreate() in a few areas, as you can see, but no luck so far.
Here is my class so far:
import android.app.Activity;
import android.content.*;
import android.os.AsyncTask;
public class MyClipBoard extends Activity {
public String clip;
MyClipBoard() {
super.onCreate(null);
}
public void getClipBoard(){
new GetClipBoard().execute();
}
private class GetClipBoard extends AsyncTask<Void, Void, String> {
private String pMyClip;
#Override
protected String doInBackground(Void...params) {
try {
onCreate(null);
// ClipboardManager p = params[0];
String pasteData = "";
ClipboardManager myClipBoard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData.Item myClip = myClipBoard.getPrimaryClip().getItemAt(0);
CreateDeviceInfoFile.createInfoFile("Data from ClipBoard:", myClip.toString());
CreateDeviceInfoFile.createInfoFile("Number of Items:", String.valueOf(myClipBoard.getPrimaryClip().getItemCount()));
pMyClip = myClip.toString();
}catch (Exception e){
CreateDeviceInfoFile.createInfoFile("ERROR",e.toString());
}
// Gets the clipboard as text.
return pMyClip;
}
#Override
protected void onPostExecute(String result) {
clip = result;
CreateDeviceInfoFile.createInfoFile("Data from PostExecute:", result);
}
}
}
---------Edited added class-------------------
public class MiApp extends Application {
public MiClipBoard newBoard;
private static Context appContext;
MiApp(){
this.onCreate();
Looper.prepare();
newBoard = new MiClipBoard();
}
public MiClipBoard appClipBoard(){
return newBoard;
}
#Override
public void onCreate(){
super.onCreate();
}
public static Context getContext(){
return appContext.getApplicationContext();
}
}
public class MiClipBoard extends Activity {
private ClipboardManager clipboard;
MiClipBoard(){
Context context = MiApp.getContext();
clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
}
public void writeToClipBoard(String clipText){
try {
ClipData clip = ClipData.newPlainText("simple text", "Hello, World!");
clipboard.setPrimaryClip(clip);
CreateDeviceInfoFile.createInfoFile("Writing to ClipBoard", "Hello World");
} catch (Exception e){
CreateDeviceInfoFile.createInfoFile("Write Error", e.toString());
}
}
public void readClipBoard(){
String pasteData = "";
try {
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
pasteData = item.getText().toString();
CreateDeviceInfoFile.createInfoFile("From ClipBoard", pasteData);
} catch (Exception e){
CreateDeviceInfoFile.createInfoFile("Read Error", e.toString());
}
}
}
Android system only allow us to activate one Activity at a time, and the others are in onPause() state. Starting an activity should have a layout.xml, and must call startActivity(Intent).
From the logcat:
"java.lang.IllegalStateException: System services not available to Activities before onCreate()".
We can know that getSystemService() only available after super.onCreate(Bundle), which triggers the activity to be created.
A good practice to call getSystemService() in non-activity class is by passing Context parameter to GetClipBoard's constructor and make it as public:
public class GetClipBoard extends AsyncTask<Void, Void, String> {
private Context context;
public GetClipBoard(Context context){
this.context = context;
}
private String pMyClip;
#Override
protected String doInBackground(Void...params) {
try {
// ClipboardManager p = params[0];
String pasteData = "";
ClipboardManager myClipBoard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
...
}catch (Exception e){
...
}
// Gets the clipboard as text.
return pMyClip;
}
...
}
So once you executing AsyncTask, call the class from Android components that has Context, e.g. Activity, Service, BroadcastReceiver, etc.
new GetClipBoard(this).execute(); // 'this' > context
I believe that is my issue, currently I don't think I have a component that has Context. This is the class I am making the call from (part of it) and the first class that is being called by adb runtest.
public class SetupApp extends UiAutomatorTestCase {
public void testAppSetup() throws UiObjectNotFoundException, RemoteException
{
//other code here
MyClipBoard myBoard = new MyClipBoard();
myBoard.getClipBoard();

Start Activity from Non-Activity

I have an Activity class.
public class A extends Activity
{
}
Then I have a class that is not an Activity but I want it to start the Activity A.
public class B
{
public B()
{
Intent I = new Intent(null, A.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
}
The code is take from this question which should work: Calling startActivity() from outside of an Activity?
However, when I run it I never change from my first activity to activity A. What am I doing wrong? Should I be listening to the FLAG_ACTIVITY_NEW_TASK inside A?
Something like this should work:
public class B {
Context context;
public B(Context context) {
this.context = context;
}
public void startNewActivity(String str) {
try {
Intent i = new Intent(context, Class.forName(str));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Use case of class B:
B b = new B(A.this);
b.startNewActivity("MainActivity");//the "MainActivity" is the className of the java class
Note I find this way wierd and a overkill.

Android - AsyncTask class in Activity class. Context crash the app

I'm creating AsyncTask class in Activity class. I need to get the Context in AsyncTask to build AlertDialog. I'm using constructor to point the context. My code:
public class Plan extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.plan);
//// some Activity code....
class fillSpiners extends AsyncTask<String, Void, String>{
private Context context;
public fillSpiners(Context context){
this.context = context;
}
#Override
protected String doInBackground(String... params) {
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert
.setTitle("Title");
/// setting up alert
AlertDialog showAlert = alert.create();
showAlert.show();
String s;
///making s String stuff...
return s;
}
} /// end of the AsyncTask class
/// now calling the fillSpiners method.
try {
String a = new fillSpiners(this).execute().get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I've read about using constructor to give context to the alert dialog, but this code stops the app(crash). I think the context is problem here.
Because you are not passing context, context in your case is null. First create constructior for your async task inside of him. Wrote on fast.
fillSpiners(Context context)
{
this.context = context;
}
Second run it:
new fullSpiners(Plan.this).execute(params);
Something like that;
OK. I know what is going on. I found this on stack overflow:
The problem is 'You can show AlertDialogs from Activity only'. This is not an issue of context.

ending android activity from surfaceview using thread.join

I'm working on my first app for android - snake. Right now I'm trying to implement 'game over' for that app. So basically when the snake hits the wall, app should ask your name and put it witch your score on HiScore. Well i'm stuk on hitting the wall fragment. Im experimenting with threads and so far I've found no way to stop it without getting errors.
I googled a lot, and everyone is saying that thread.join(); is waiting for thread to end, so how long does it take to end the thread that is drawing simple squares once per half second? When im hitting the back button on my phone while playing, pause(); function works perfectly. Log "game has ended" appears on LogCat.
So the problem is that i cant stop this activity when snake hits the wall, Log "game has ended" never occurs. Why is that?
My code:
public class SnakeCage extends SurfaceView implements Runnable{
// blah blah .. functions that draw and stuff ..
public void pause() {
isRunning = false;
while(true){
try {
aThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
aThread = null;
Log.d("pause()","game has ended"); // <<<<<<<<<THIS ONE>>>>>>>>>
}
public void resume() {
isRunning = true;
aThread = new Thread(this);
aThread.start();
}
public void init(){
// blah blah...
}
private void gameOver() {
int pHeadX = snakeHead.posX;
int pHeadY = snakeHead.posY;
Log.d("gameOver()", "checking");
if(pHeadY<0 || pHeadX<0 || pHeadX>23 || pHeadY>19){
Log.d("gameOver()", "game now will end");
gameOver = true;
}
}
public void run() {
while (isRunning){
if(!aHolder.getSurface().isValid())
continue;
canvas = aHolder.lockCanvas();
// drawing
gameOver();
if(gameOver) break;
// more drawing
aHolder.unlockCanvasAndPost(canvas);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(gameOver){
pause();
}
}
and the activity class:
public class PlayingActivity extends Activity implements OnClickListener{
SnakeCage v;
Button snakeGoUp;
Button snakeGoDown;
Button snakeGoLeft;
Button snakeGoRight;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frame_layout);
v = (SnakeCage)findViewById(R.id.sView);
// listeners and stuff
}
#Override
protected void onPause() {
super.onPause();
v.pause();
}
#Override
protected void onResume() {
super.onResume();
v.resume();
}
#Override
public void onClick(View view) {
switch(view.getId()){
case R.id.snakeUp:
v.move(1);
break;
case R.id.snakeDown:
v.move(2);
break;
case R.id.snakeLeft:
v.move(3);
break;
case R.id.snakeRight:
v.move(4);
break;
}
}
}
i just did:
Context context = getContext();
((PlayingActivity)context).finish();
from:
How can I end an activity from inside a SurfaceView class or nested thread
although it does not satisfy me... its enough for now
I would suggest using a LocalBroadcastManager to send a message to the Activity, to notify it to kill itself. You can have an inner class in the Activity to receive the broadcast and call a private method in the Activity which will end it.
public class MyActivity extends Activity {
public void onCreate(Bundle state) {
LocalBroadcastManager.getInstance(this).registerReceiver(new MessageHandler(),
new IntentFilter("kill"));
}
private void killActivity() {
finish();
}
public class MessageHandler extends BroadcastReceiver {
onReceive(Context context, Intent intent) {
killActivity();
}
}
Then in your SurfaceView all you need to do is:
Intent intent = new Intent("kill");
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
Its a little more code but its a lot cleaner IMHO.

Categories