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
Related
here is my manifest file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="sam.ulf.myapplication3">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<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.MyApplication3"
tools:targetApi="31">
<activity
android:name=".NotificationActivity"
android:exported="false" />
<activity
android:name=".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=".FirebaseBackgroundService"
android:exported="false"
android:process=":remote" >
<intent-filter>
<action android:name="sam.ulf.myapplication3.FirebaseBackgroundService"/>
</intent-filter>
</service>
<receiver android:name=".StartFirebaseAtBoot"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" >
</action>
</intent-filter>
</receiver>
</application>
</manifest>
and here is my mainactivity
package sam.ulf.myapplication3;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import android.app.ActivityManager;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.FirebaseApp;
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 com.google.firebase.messaging.FirebaseMessaging;
import java.io.Serializable;
import java.util.List;
public class MainActivity extends AppCompatActivity {
Button on,on2;
Button off,off2;
TextView distance;
DatabaseReference dref;
String status;
//FirebaseFirestore firestore;
//Button btn3 ,btn4;
TextView sens1,sens2,sens3,sens4;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseApp.initializeApp(this);
// startService(new Intent(FirebaseBackgroundService.class.getName()));
startService(new Intent(this, FirebaseBackgroundService.class));
//FirebaseBackgroundService s= new FirebaseBackgroundService();
// s.addDataToDatabase();
sens1=(TextView)findViewById(R.id.sensor1);
sens2=(TextView)findViewById(R.id.sensor2);
sens3=(TextView)findViewById(R.id.sensor3);
sens4=(TextView)findViewById(R.id.sensor4);
status="";
on2=(Button)findViewById(R.id.on2);
off2=(Button)findViewById(R.id.off2);
on = (Button) findViewById(R.id.on);
off = (Button) findViewById(R.id.off);
distance = (TextView) findViewById(R.id.distance);
dref= FirebaseDatabase.getInstance().getReference();
dref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
checkService();
status=dataSnapshot.child("database").getValue().toString();
distance.setText(status);
status=dataSnapshot.child("sensor1").getValue().toString();
sens1.setText(status);
status=dataSnapshot.child("sensor2").getValue().toString();
sens2.setText(status);
status=dataSnapshot.child("sensor3").getValue().toString();
sens3.setText(status);
status=dataSnapshot.child("sensor4").getValue().toString();
sens4.setText(status);
String msg="ched lheme";
//NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this,"my notifcation").setSmallIcon(R.drawable.ic_msg)
// .setContentTitle("balesh che8el").setContentText(msg).setAutoCancel(true);
//Intent intent = new Intent(MainActivity.this,NotificationActivity.class);
//intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//intent.putExtra("message",msg);
//PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
// builder.setContentIntent(pendingIntent);
//NotificationManager notificationManager =(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
// NotificationManagerCompat managerCompat =NotificationManagerCompat.from(MainActivity.this);
// managerCompat.notify(1,builder.build());
// NotificationChannel channel = new NotificationChannel("My Notifcation","My Notifcation",NotificationManager.IMPORTANCE_DEFAULT);
// NotificationManager manager =getSystemService(NotificationManager.class);
//manager.createNotificationChannel(channel);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
on.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("LED_STATUS");
myRef.setValue("1");
}
});
on2.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("LED_STATUS2");
myRef.setValue("1");
}
});
off.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("LED_STATUS");
myRef.setValue("0");
}
});
off2.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("LED_STATUS2");
myRef.setValue("0");
}
});
}
public void checkService(){
if(isServiceRunning(getApplicationContext(),FirebaseBackgroundService.class)){
Toast.makeText(getApplicationContext(),"service is running",Toast.LENGTH_LONG).show();
}
else
Toast.makeText(getApplicationContext(),"service is not running",Toast.LENGTH_LONG).show();
}
public boolean isServiceRunning(Context c,Class<?>serviceClass) {
ActivityManager activityManager = (ActivityManager) c.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
for (ActivityManager.RunningServiceInfo runningServiceInfo : services) {
if (runningServiceInfo.service.getClassName().equals(serviceClass.getName())) {
return true;
}
;
}
return false;
}
}
and this is my firebasebackground service class
package sam.ulf.myapplication3;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.google.firebase.*;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.DatabaseRegistrar;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.ktx.Firebase;
public class FirebaseBackgroundService extends Service {
private Context mContext;
private DatabaseReference data;
//private Firebase f = new firebase("https://somedemo.firebaseio-demo.com/");
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference orders = database.getReference();
private ValueEventListener handler;
#Override
public IBinder onBind(Intent arg0) {
// FirebaseApp.initializeApp(this);
return null;
}
// #Override
// public int onStartCommand(Intent intent, int flags, int startId) {
// // FirebaseApp.initializeApp(this);
// mContext=getApplicationContext();//Get the context here
// FirebaseDatabase database2 = FirebaseDatabase.getInstance();
//
// DatabaseReference orders2 = database2.getReference("test");
// orders2.setValue("kolol");
// // addDataToDatabase();
// Toast.makeText(this, "Service started by user.", Toast.LENGTH_LONG).show();
//
// new Thread(new Runnable() {
// #Override
// public void run() {
// while(true){
//
// Log.e("service","service is running");
// }
// }
// });
// // return super.onStartCommand(intent, flags, startId);
// return START_STICKY;
// }
#Override
public void onCreate() {
super.onCreate();
// FirebaseApp.initializeApp(this);
addDataToDatabase();
showToast();
Toast.makeText(this,"test", Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(),"test", Toast.LENGTH_SHORT).show();
orders.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
postNotif("ntebeh");
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
handler = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot arg0) {
postNotif(arg0.getValue().toString());
Log.e("service","service eners change");
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
};
orders.addValueEventListener(handler);
}
void postNotif(String notifString) {
Log.e("service","service is running2");
Toast.makeText(this,"test", Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(),"test", Toast.LENGTH_SHORT).show();
NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
Toast.makeText(this,"test", Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(),"test", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);
// build notification
// the addAction re-use the same intent to keep the example short
Notification n = new Notification.Builder(this)
.setContentTitle("My message")
.setContentText("Subject")
.setSmallIcon(R.drawable.ic_msg)
.setContentIntent(pIntent)
.setAutoCancel(true)
.setStyle(new Notification.BigTextStyle().bigText("")).build();
// .addAction(R.drawable.line, "", pIntent).build();
n.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, n);
}
void showToast() {
if (mContext != null) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(mContext, "Display your message here", Toast.LENGTH_LONG).show();
}
});
}
}
public void addDataToDatabase() {
//setValue method is used to add value to RTFD
orders.setValue("kol",1
);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service destroyed by user.", Toast.LENGTH_LONG).show();
}
}
and this is startfirebaseatboot class
package sam.ulf.myapplication3;
import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.google.firebase.FirebaseApp;
/**
* Start the service when the device boots.
*
* #author vikrum
*
*/
public class StartFirebaseAtBoot extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, FirebaseBackgroundService.class));
}
}
and this is build.gradle
buildscript {
repositories {
// Check that you have the following line (if not, add it):
google() // Google's Maven repository
}
dependencies {
// Add this line
classpath 'com.google.gms:google-services:4.3.10'
//classpath 'com.google.gms:google-services:4.0.1'
//classpath 'com.google.gms:google-services:4.2.0'
}
}
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.2.1' apply false
id 'com.android.library' version '7.2.1' apply false
}
task clean(type: Delete) {
delete rootProject.buildDir
}
i get this error 2022-06-20 03:49:18.983 1417-1417/sam.ulf.myapplication3 E/AndroidRuntime: FATAL EXCEPTION: main
Process: sam.ulf.myapplication3:remote, PID: 1417
java.lang.RuntimeException: Unable to create service sam.ulf.myapplication3.FirebaseBackgroundService: java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process sam.ulf.myapplication3:remote. Make sure to call FirebaseApp.initializeApp(Context) first.
i tried to initialize firebase in mainactivity and also tried to initialize it in service class but it didnt work , im trying to send notification when firebase data change even if the app is not running or terminated.
i know firebase has cloud function but they are not free so im trying to use background service i found this code on github https://gist.github.com/vikrum/6170193
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>
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);
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>
...
I have a class for receiving sms:
package com.example.app;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.gsm.SmsManager;
import android.telephony.gsm.SmsMessage;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
public class SmsReceiver extends BroadcastReceiver
{
// Get the object of SmsManager
final SmsManager sms = SmsManager.getDefault();
public void onReceive(Context context, Intent intent) {
Log.i("SmsReceiver", "senderNum: ");
// Retrieves a map of extended data from the intent.
final Bundle bundle = intent.getExtras();
try {
if (bundle != null) {
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
String phoneNumber = currentMessage.getDisplayOriginatingAddress();
String senderNum = phoneNumber;
String message = currentMessage.getDisplayMessageBody();
Log.i("SmsReceiver", "senderNum: "+ senderNum + "; message: " + message);
// Show Alert
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context,
"senderNum: "+ senderNum + ", message: " + message, duration);
toast.show();
} // end for loop
} // bundle is null
} catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" +e);
}
}
}
MainActivity:
package com.example.app;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("SmsReceiver", "senderNum: ");
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.app.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<receiver android:name=".SmsReceiver">
<intent-filter>
<action android:name=
"android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</activity>
</application>
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
</manifest>
The method onReceive doesn't executes. I can see it in logs (no logs). I am sending sms through telnet - emulator receives sms but app not. Why ? What's wrong ?
Just take a look here http://developer.android.com/guide/topics/manifest/receiver-element.html
receiver is contained inside application node. Move it out of activity
IntentFilter filter = new IntentFilter("IntentTag");
registerReceiver(new SmsReceiver(), filter);