I can't start activity from service while app is hidden - java

I have two activities: MainActivity and ActivityTwo. When starting application, I start service serviceApp, which after some events should start ActivityTwo. For the test, I made the launch after 10 seconds and AsyncTask, but if the application is hidden, activity does not start
How do I launch activity even if the app is hidden?
MainActivity
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SwitchCompat;
import android.app.ActivityManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import java.security.Provider;
import java.util.List;
public class MainActivity extends AppCompatActivity {
SharedPreferences setting;
#Override
protected void onCreate(Bundle savedInstanceState) {
Intent service = new Intent(this, serviceApp.class);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setting = getSharedPreferences("settings", MODE_PRIVATE);
SwitchCompat switchCompat = findViewById(R.id.switchBLock);
switchCompat.setOnCheckedChangeListener((view, bool) -> {
SharedPreferences.Editor editor = setting.edit();
editor.putBoolean("block", bool);
editor.apply();
if(bool){
startService(service);
}else{
stopService(service);
}
});
if(setting.getBoolean("block", false)){
switchCompat.setChecked(true);
}
}
}
ActivityTwo
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
public class ActivityTwo extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_two);
}
}
serviceApp
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
public class serviceApp extends Service {
Context context;
public serviceApp() {
context = this;
}
#Override
public void onCreate() {
super.onCreate();
new Async().execute();
}
class Async extends AsyncTask<Void, Void, Void>{
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Intent startMain = new Intent();
startMain.setClass(context, ActivityTwo.class);
startMain.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
}
#Override
protected Void doInBackground(Void... voids) {
for(int i = 0; i < 2; i++) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.NoActionBar">
<activity android:name="com.example.test.ActivityTwo"></activity>
<service
android:name=".serviceApp"/>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

I found an easy way to fix this ailment, you need to give the application the SYSTEM_ALERT_WINDOW permission
https://developer.android.com/guide/components/activities/background-starts
AndroidManifest.xml
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
MainActivity
Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(myIntent);

Related

How to fill the progress bar in the background while changing activities

I have 3 page application, in which the activities change every 10 secs (i.e., Activity1 -> Activity2 -> Activity3 -> Activity1 .......).
I have a progressbar in Activity2 which updates every 1 sec. The problem is, whenever the Activity2 is changing to Activity3 and then coming back to Activity 2 the progressbar is resetting and starting all over from zero.
I would like the progressbar to update continuously for the set time without interruptions. I tried using the services but the result is still the same.
I hope the code below helps in idenfying the issue and would really appreciate if anyone helps me out.
Activity1.java
package com.ossus.SC20;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
public class frame_6_activity extends Activity {
Timer timer;
private View _bg__frame_6;
private ImageView background_1;
private TextView text_view_date;
private ImageView logo_2_1;
private TextView H2Value;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frame_6);
startService(new Intent(frame_6_activity.this, service.class));
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this));
if (getIntent().getBooleanExtra("crash", false)) {
Toast.makeText(this, "App restarted after crash", Toast.LENGTH_SHORT).show();
}
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run(){
Intent intent = new Intent(frame_6_activity.this, frame_2_activity.class);
startActivity(intent);
finish();
}
}, 10000);
Calendar calendar = Calendar.getInstance();
String currentDate = DateFormat.getDateInstance(DateFormat.FULL).format(calendar.getTime());
TextView textViewDate = findViewById(R.id.text_view_date);
textViewDate.setText(currentDate);
_bg__frame_6 = (View) findViewById(R.id._bg__frame_6);
background_1 = (ImageView) findViewById(R.id.background_1);
text_view_date = (TextView) findViewById(R.id.text_view_date);
logo_2_1 = (ImageView) findViewById(R.id.logo_2_1);
H2Value = (TextView) findViewById(R.id.H2Value);
}
}
Activity2.java
package com.ossus.SC20;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import org.w3c.dom.Text;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
public class frame_2_activity extends Activity {
private ProgressBar mProgressBar;
private TextView mLoadingText;
private int mProgressStatus = 0;
// private Handler mHandler = new Handler();
Handler handler = new Handler();
Timer timer;
private View _bg__frame_2;
private ImageView background_1;
private TextView text_view_date;
private ImageView logo_2_1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frame_2_new);
startService(new Intent(frame_2_activity.this, service.class));
mProgressBar = (ProgressBar) findViewById(R.id.progressbar);
mLoadingText = (TextView) findViewById(R.id.LoadingCompleteTextView);
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
startProgress();
}
});
thread.start();
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run(){
Intent intent = new Intent(frame_2_activity.this, frame_3_activity.class);
startActivity(intent);
finish();
}
}, 10000);
Calendar calendar = Calendar.getInstance();
String currentDate = DateFormat.getDateInstance(DateFormat.FULL).format(calendar.getTime());
TextView textViewDate = findViewById(R.id.text_view_date);
textViewDate.setText(currentDate);
_bg__frame_2 = (View) findViewById(R.id._bg__frame_2);
background_1 = (ImageView) findViewById(R.id.background_1);
text_view_date = (TextView) findViewById(R.id.text_view_date);
logo_2_1 = (ImageView) findViewById(R.id.logo_2_1);
//custom code goes here
}
public void startProgress(){
for (mProgressStatus = 0; mProgressStatus < 100; mProgressStatus = mProgressStatus + 1){
try{
Thread.sleep(1000);
mProgressBar.setProgress(mProgressStatus);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
#Override
public void run() {
mLoadingText.setText(String.valueOf(mProgressStatus + "% Completed"));
}
});
}
}
}
Service.java
package com.ossus.SC20;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class service extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service started by user.", Toast.LENGTH_LONG).show();
return START_STICKY;
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.ossus.SC20">
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.SC20"
tools:targetApi="31">
<activity
android:name=".frame_3_activity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"
android:screenOrientation="landscape"
android:exported="true" >
</activity>
<activity
android:name=".frame_2_activity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"
android:screenOrientation="landscape"
android:exported="true" >
</activity>
<activity
android:name=".frame_6_activity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"
android:screenOrientation="landscape"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="preloaded_fonts"
android:resource="#array/preloaded_fonts" />
<service android:name = ".service"/>
</application>
</manifest>

Unable to add view to a window with TYPE_PHONE params android

I am trying to create a floating view which should appear on top of everything but notification panel and settings app hide my view
I tried to use WindowManager.LayoutParams.TYPE_PHONE but its deprecated after oreo and app crashes if I try to add a view to that window with params set to WindowManager.LayoutParams.TYPE_PHONE
here is my java code
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.opengl.Visibility;
import android.os.IBinder;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;
public class FloatingMouseService extends Service {
private WindowManager mWindowManager;
private View floatingMouse;
public FloatingMouseService() {
}
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
super.onCreate();
LayoutInflater layoutInflater = (LayoutInflater) FloatingMouseService.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
floatingMouse = layoutInflater.inflate(R.layout.layoutmouse, null);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 100;
mWindowManager = (WindowManager) FloatingMouseService.this.getSystemService(WINDOW_SERVICE);
mWindowManager.addView(floatingMouse, params);
}
}
here is MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final int CODE_DRAW_OVER_OTHER_APP_PERMISSION = 2084;
TextView serMess = findViewById(R.id.serMess);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, CODE_DRAW_OVER_OTHER_APP_PERMISSION);
} else {
initializeView();
}
}
private void initializeView() {
Button connect = findViewById(R.id.connect);
findViewById(R.id.connect).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startService(new Intent(MainActivity.this, FloatingMouseService.class));
new Thread(new ClientServerReq()).start();
Toast.makeText(MainActivity.this, "Connected Successfully", Toast.LENGTH_SHORT).show();
connect.setText("Connected");
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
final int CODE_DRAW_OVER_OTHER_APP_PERMISSION = 2084;
if (requestCode == CODE_DRAW_OVER_OTHER_APP_PERMISSION) {
if (resultCode == RESULT_OK) {
initializeView();
} else { //Permission is not available
Toast.makeText(this,
"Draw over other app permission not available. Closing the application",
Toast.LENGTH_SHORT).show();
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
#Override
protected void onResume() {
super.onResume();
}
}
here is my Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.MFB.project.sharekey">
<uses-permission android:name="android.permission.INTERNET" ></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" ></uses-permission>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.DayNight.DarkActionBar">
<activity
android:name="com.MFB.project.sharekey.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.MFB.project.sharekey.FloatingMouseService"
android:enabled="true" />
</application>
</manifest>

Playback position resets to zero after orientation change

Below is the code for my music player. I use Videoview to play a local list of selective songs.
I want to store and resume the playback position when orientation changes (portrait/landscape).
I have used onSaveInstanceState and onRestoreInstanceState methods. No errors on build, but still the songs reset every time.
I couldn't figure out what's wrong.
package io.automaton.android.morningbinge;
import androidx.appcompat.app.AlertDialog;
import android.app.Activity;
import android.content.DialogInterface;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Toast;
import android.widget.VideoView;
import android.widget.MediaController;
import java.util.ArrayList;
public class MainActivity extends Activity
implements MediaPlayer.OnCompletionListener {
VideoView vw;
ArrayList<Integer> videolist = new ArrayList<>();
int currvideo = 0;
int mPositionWhenPaused=0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vw = (VideoView)findViewById(R.id.videoView);
vw.setMediaController(new MediaController(this));
vw.setOnCompletionListener(this);
// video name should be in lower case alphabet.
videolist.add(R.raw.onbadhu_kolum);
videolist.add(R.raw.kala_bhairava_ashtakam);
videolist.add(R.raw.panchamukh_hanumath_kavacham);
videolist.add(R.raw.kandha_shashti_kavasam);
setVideo(videolist.get(0));
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
//we use onSaveInstanceState in order to store the video playback position for orientation change
savedInstanceState.putInt("Position", vw.getCurrentPosition());
vw.pause();
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//we use onRestoreInstanceState in order to play the video playback from the stored position
mPositionWhenPaused = savedInstanceState.getInt("Position");
vw.seekTo(mPositionWhenPaused);
}
public void setVideo(int id)
{
String uriPath
= "android.resource://"
+ getPackageName() + "/" + id;
Uri uri = Uri.parse(uriPath);
vw.setVideoURI(uri);
vw.start();
}
public void onCompletion(MediaPlayer mediapalyer)
{
AlertDialog.Builder obj = new AlertDialog.Builder(this);
obj.setTitle("Playback Finished!");
obj.setIcon(R.mipmap.ic_launcher);
MyListener m = new MyListener();
obj.setPositiveButton("Replay", m);
obj.setNegativeButton("Next", m);
obj.setMessage("Want to replay or play next video?");
obj.show();
}
class MyListener implements DialogInterface.OnClickListener {
public void onClick(DialogInterface dialog, int which)
{
if (which == -1) {
vw.seekTo(0);
vw.start();
}
else {
++currvideo;
if (currvideo == videolist.size())
currvideo = 0;
setVideo(videolist.get(currvideo));
}
}
}
}
I sorted out the issue. I changed the way the list is being called to play with the setOnPreparedListener, seeking to last played position.
...
Main Activity
package io.automaton.android.morningbinge;
import androidx.appcompat.app.AlertDialog;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.res.Configuration;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import android.widget.VideoView;
import android.widget.MediaController;
import android.media.MediaPlayer.OnPreparedListener;
import java.util.ArrayList;
public class MainActivity extends Activity
implements MediaPlayer.OnCompletionListener {
VideoView vw;
ArrayList<Integer> videolist = new ArrayList<>();
int currvideo = 0;
int mPositionWhenPaused=0;
private static final String TAG = "MyActivity";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vw = (VideoView)findViewById(R.id.videoView);
vw.setMediaController(new MediaController(this));
vw.setOnCompletionListener(this);
videolist.add(R.raw.onbadhu_kolum);
videolist.add(R.raw.kala_bhairava_ashtakam);
videolist.add(R.raw.panchamukh_hanumath_kavacham);
videolist.add(R.raw.kandha_shashti_kavasam);
try {
//set the uri of the video to be played
vw.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + videolist.get(0)));
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
vw.requestFocus();
vw.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mediaPlayer) {
vw.seekTo(mPositionWhenPaused);
if (mPositionWhenPaused == 0) {
vw.start();
} else {
vw.pause();
}
}
});
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("Position", vw.getCurrentPosition());
Log.i("Orientation Change", "Warn-orientation change and saved");
vw.pause();
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mPositionWhenPaused = savedInstanceState.getInt("Position");
vw.seekTo(mPositionWhenPaused);
Log.i("restored", "restored after orientation change");
}
public void onCompletion(MediaPlayer mediapalyer)
{
++currvideo;
if (currvideo == videolist.size())
currvideo = 0;
setVideo(videolist.get(currvideo));
}
}
...
android manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="io.automaton.android.morningbinge">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
...

For some reason data is not sent from 3rd Activity to main Activity and the app crashes while the 2nd Activity works perfectly fine

package com.example.intent;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
EditText etEnterName;
Button btnActivity2;
Button btnActivity3;
TextView tvMessage;
final int ACTIVITY3=3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etEnterName=findViewById(R.id.etEnterName);
btnActivity2=findViewById(R.id.btnActivity2);
btnActivity3=findViewById(R.id.btnActivity3);
btnActivity2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (etEnterName.getText().toString().isEmpty()) {
Toast.makeText(MainActivity.this, "please enter all fields", Toast.LENGTH_SHORT).show();
}
else {
String name = etEnterName.getText().toString().trim();
Intent intent = new Intent(MainActivity.this,
com.example.intent.Activity2.class);
intent.putExtra("name",name);
startActivity(intent);
}
}
});
btnActivity3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,
com.example.intent.Activity3.class);
startActivityForResult(intent,ACTIVITY3);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==ACTIVITY3)
{
if (resultCode==RESULT_OK){
tvMessage.setText(data.getStringExtra("surname"));
}
if(resultCode==RESULT_CANCELED){
tvMessage.setText("no data received");
}
}
}
}
3rd Activity
package com.example.intent;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class Activity3 extends AppCompatActivity {
Button btnSubmit;
EditText etSurname;
Button btnCancel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_3);
btnSubmit=findViewById(R.id.btnSubmit);
etSurname=findViewById(R.id.etSurname);
btnCancel=findViewById(R.id.btnCancel);
btnSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(etSurname.getText().toString().isEmpty()){
Toast.makeText(Activity3.this,"please enter your surname" Toast.LENGTH_SHORT).show();
}
else {
String surname = etSurname.getText().toString().trim();
Intent intent = new Intent();
intent.putExtra("surname",surname);
setResult(RESULT_OK,intent);
Activity3.this.finish();
}
}
});
btnCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setResult(RESULT_CANCELED);
Activity3.this.finish();
}
});
}
}
This is the manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.intent">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".Activity3"></activity>
<activity android:name=".Activity2" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Explanation
Blockquote
I following a youtube video and i cant find where i am getting the whole thing wrong. The button main activity works perfectly fine and take me to the third intent but when i enter data in edit text box and click the submit button the app crashes.
I had not added this line of code.
tvMessage = findviewbyid (R.id.tvMessage);
My bad –

App is stopped on getContentResolver().query(...) when SMS is sent

Good day, I am programming application about catching the sent messages. Everything is working, the ContentObserver is called everytime when I try to send a SMS, but in onChange(boolean selfChange) method the application drops on the :
Cursor cur = getContentResolver().query(uriSMS, null, null, null, null)
.............................. screen http://imgur.com/a/hE94K
in TrackerService.java in mObserver. When I am debbuging that via Step Over (F8), on this line It open me a Looper.java and drops on this lines http://imgur.com/a/uh4Dl ... How to fix that for working please? I hope you will understand my problem and sorry for my bad english. Thank you so much!
MainActivity.java
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
Intent serviceIntent;
private static MyReceiver mServiceReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onPause() {
Log.i("Status","Pause");
unregisterReceiver(mServiceReceiver);
super.onPause();
}
#Override
protected void onResume() {
Log.i("Status","Resume");
serviceIntent = new Intent(MainActivity.this, TrackerService.class);
startService(serviceIntent);
mServiceReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TrackerService.mAction);
registerReceiver(mServiceReceiver, intentFilter);
super.onResume();
}
private class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
Log.i("ServiceReceiver", "onReceive()");
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
TrackerService.java
import android.app.Service;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
public class TrackerService extends Service
{
public static final String mAction = "SMSTracker";
ContentResolver content;
ContentResolver contentResolver;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("Status","Service Start");
contentResolver = this.getContentResolver();
contentResolver.registerContentObserver(Uri.parse("content://sms/"), true, new mObserver(new Handler()));
return super.onStartCommand(intent, flags, startId);
}
class mObserver extends ContentObserver {
public mObserver(Handler handler) {
super(handler);
}
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Log.i("Status","onChange");
Uri uriSMS = Uri.parse("content://sms/out/");
Cursor cur = getContentResolver().query(uriSMS, null, null, null, null);
//Log.i("SMS", "Columns: " + cur.getColumnNames());
cur.moveToNext();
String smsText = cur.getString(cur.getColumnIndex("body"));
Log.i("SMS", "SMS Lenght: " + smsText.length());
}
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i("Status","Service Destroy");
}
#Override
public IBinder onBind(Intent intent) {
Log.i("Status","Service Bind");
return null;
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="wut.com.smstry">
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
<uses-permission android:name="android.permission.READ_SMS"></uses-permission>
<application
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".TrackerService" />
</application>
</manifest>
Make sure you're registering for the right content path. Ex:-
Inbox = "content://sms/inbox"
Failed = "content://sms/failed"
Queued = "content://sms/queued"
Sent = "content://sms/sent"
Draft = "content://sms/draft"
Outbox = "content://sms/outbox"
Undelivered = "content://sms/undelivered"
All = "content://sms/all"
Conversations = "content://sms/conversations".
contentResolver.registerContentObserver(Uri.parse("content://sms/outbox"), true, new mObserver(new Handler()));
Similarly use the same path on the cursor.query

Categories