Pass array from activity to service (Android) - java

i'm beginner to java and i'm trying to do the following: in MainActivity generate an array and pass it to the Service. The difficulty lies precisely in how to pass this array to the Service. Yes, I saw that there are many similar questions, but I can't understand the principle of how this happens.
What can you advise me?
MainActivity.java
package com.example.myservice;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int[] arr = new int[5];
StringBuilder num = new StringBuilder();
for(int i = 0; i < 5; i++) {
arr[i] = (int) (Math.random() * 10);
num.append(arr[i]).append(" ");
}
TextView textView = findViewById(R.id.textView2);
textView.setText(num);
startService(new Intent(this, MyService.class));
}
}
MyService.java
package com.example.myservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
#Override
public void onCreate(){
Log.i("MyLog", "onCreate");
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}

in MainActivity start your service like this
Intent intent =new Intent(this,MyService.class);
intent.putExtra("myArray",arr);
startService(intent);
on your service override onStartCommand method
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
int myList[]=intent.getIntArrayExtra("myArray");
for (int item:myList){
Log.i("MyLog", "onStartCommand: "+item);
}
return super.onStartCommand(intent, flags, startId);
}
and don't forget to declare your service on AndroidManifest file inside Application tag add
<service android:name=".MyService"/>

Related

How do I access my UI from MainActivity from Broadcast Receiver class

I am new to Android Studio and I am creating a custom notification app, and I wanted to use the EditText from my MainActivity class in Broadcast Receiver class. How can I do that?
Broadcast Receiver code:
`package com.example.notificationscreator;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.widget.EditText;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationCompat.Builder Build = new NotificationCompat.Builder(context, "Notified");
Build.setSmallIcon(R.drawable.ic_stat_name);
Build.setContentTitle("");
Build.setStyle(new NotificationCompat.BigTextStyle().bigText(""));
NotificationManagerCompat Managercompats = NotificationManagerCompat.from(context);
Managercompats.notify(1, Build.build());
}
}`
Main activity code:
`package com.example.notificationscreator;
import static com.example.notificationscreator.R.*;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import android.app.AlarmManager;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.util.Calendar;
import java.util.Random;
public class MainActivity2 extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(layout.activity_main2);
Button btnmain = findViewById(R.id.button4);
Button Displaynotif = findViewById(R.id.button3);
EditText Timedisplay = findViewById(R.id.editTextTime);
Integer Time = Integer.parseInt(Timedisplay.getText().toString());
btnmain.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Backmainpage();
}
});
if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.O){
NotificationChannel channel = new NotificationChannel("Notified","Notification", NotificationManager.IMPORTANCE_HIGH);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
}
Displaynotif.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int Randnum = new Random().nextInt(80);
Intent intent= new Intent(MainActivity2.this,MyReceiver.class);
PendingIntent pendingintention = PendingIntent.getBroadcast(MainActivity2.this,0, intent,0);
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
long timeonclick = System.currentTimeMillis();
long timeafterclick = 10000;
am.set(AlarmManager.RTC_WAKEUP,timeonclick+timeafterclick,pendingintention);
}
});
}
public void Backmainpage(){
Intent intention2 = new Intent(this,MainActivity.class);
startActivity(intention2);
}
}`
I've tried recalling Main Activity using
MainActivity2 Mainactivity = new MainActivity2();
but I still can't access the UI from Main Activity
You can use another BroadcastReceiver to communicate with your activity like below example.
add the following code inside your broadcast receiver.
#Override
public void onReceive(Context context, Intent intent) {
//... your other code
Intent intent = new Intent();
intent.setAction("CustomAction"); // use your action name
intent.putExtra("key", "Value"); // you can pass data like this
context.sendBroadcast(intent); // fire broadcast receiver
}
Now, register your custom broadcast receiver from Activity
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction("CustomAction"); // use your custom action name
BroadcastReceiver updateUIReciver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//You will get your data here
//Update UI based on your data.
if (intent != null) {
String data = intent.getStringExtra("key");
}
}
};
registerReceiver(updateUIReciver, filter); // register broad cast receiver.
}
public class MainActivity2 extends AppCompatActivity {
EditText Timedisplay;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(layout.activity_main2);
Timedisplay = findViewById(R.id.editTextTime);
//register your broadcast here
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("messageevent"));
}
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, final Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("key");
Log.e(TAG, "Got message: " + message);
if(message != null && !message.isEmpty()) {
//Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
String timedisplay = Timedisplay.getText();
}
}
};
//call this from anywhere you want to trigger the broadcoast
Intent i = new Intent("messageevent");
// You can also include some extra data.
i.putExtra("key", "value");
LocalBroadcastManager.getInstance(CheckUpdate.this).sendBroadcast(i);

discussing getActivityResult in class

There must be a way to get intent result in a class without using onActivityResult. By using other methods...
I dont know how, but Iam sure there is a way.
My class that should get the result of the intent filepicker from this class without using onActivityResult in the MainActivity.java that extents activity. FilePicker.java
package com.hadiawali.codeeditor;
import android.content.Intent;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
public class FilePicker {
Intent filePicker = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
public static void startPicking(Activity activity) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
Intent chooseFolder = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
chooseFolder.addCategory(Intent.CATEGORY_DEFAULT);
activity.startActivityForResult(Intent.createChooser(chooseFolder, "Choose directory"), 9999);
}
}
}
My class that extents activity. MainActivity.java
package com.hadiawali.codeeditor;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = findViewById(R.id.btn);
btn.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
FilePicker.startPicking(MainActivity.this);
//I need to get the intent reslut from the class without using onActivityResult
}
});
}
}
For example you send to intent from activity A to B then
in Activity A create Activity Result like below
ActivityResultLauncher<Intent> someActivityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
// callback called
}
}
});
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//call B activity
someActivityResultLauncher.launch(intent);
}
in Activity B your task is successfully complete then set
setResult(RESULT_OK);
finish();
or if task is not complete successfully then put
setResult(RESULT_CANCELED);
finish();

Error: View cannot be applied to Intent

I'm new to Android App Development and creating a simple service app. It has a button to start service and a button to stop service with their repective methods. Following is my code:
App3_main.java
package eg.app3;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class App3_main extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app3_main);
}
public void startservice(View view)
{
Intent intent = new Intent(this,MyService.class);
startservice(intent); //this is where I'm getting the error mentioned in the title
}
public void stopservice(View view)
{
Intent intent = new Intent(this,MyService.class);
stopservice(intent); //this is where I'm getting the error mentioned in the title
}
}
MyService.java
package eg.app3;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MyService extends Service {
public MyService() {
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"Service Started",Toast.LENGTH_LONG).show();
return START_STICKY;
}
#Override
public void onDestroy() {
Toast.makeText(this,"Service Stopped",Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Please guide me where I'm wrong.
Replace:
startservice(intent);
with:
startService(intent);
Then, replace:
stopservice(intent);
with:
stopService(intent);
Like most programming languages, Java is case-sensitive.

Creating notification once onSensorChanged method is called Android

This is the myService class:
package me.smarthwatches.simplenotification;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service implements SensorEventListener {
private static final String DEBUG_TAG = "AccelLoggerService";
private SensorManager mSensorManager;
private Sensor mSensor;
// on start command: register listener, on create:, and on destroy, Ibinder return null
//get the system service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
// return super.onStartCommand(intent, flags, startId);
return START_STICKY; // want service to continue running until its explicitly stopped so return sticky
}
#Override
public void onCreate() {
// super.onCreate();
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
public void onDestroy() {
// super.onDestroy();
mSensorManager.unregisterListener(this);
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
return;
}
#Override
public void onSensorChanged(SensorEvent event) {
if (Math.abs(event.values[0]) > 9.8 || Math.abs(event.values[1]) > 9.8 || Math.abs(event.values[2]) > 9.8) {
Log.v(MyService.DEBUG_TAG, "value is greater than 9");
//need to launch a notification? ask if person is excited?
showNotification();
}
mSensorManager.unregisterListener(this);
}
/** Notification to show person is excited */
private void showNotification() {
// create a button here asking if excited
Notification notification = new NotificationCompat.Builder(getApplication())
.setContentTitle("Excited")
.setContentText("Well are you?")
.extend(
new NotificationCompat.WearableExtender().setHintShowBackgroundOnly(true))
.build();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getApplication());
int notificationId = 2;
notificationManager.notify(notificationId, notification);
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
// throw new UnsupportedOperationException("Not yet implemented");
return null;
}
}
This is the WearActivity Class:
package me.smarthwatches.simplenotification;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.wearable.view.WatchViewStub;
import android.widget.TextView;
public class WearActivity extends Activity {
private TextView mTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wear);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
#Override
public void onLayoutInflated(WatchViewStub stub) {
mTextView = (TextView) stub.findViewById(R.id.text);
}
});
Intent serviceIntent = new Intent(getApplicationContext(), MyService.class);
startService(serviceIntent);
}
Essentially, what I'd like to do is that once the accelerometer, which is running on a service in the background, reaches a certain threshold (9.8), then I want to display something to the screen for the Wear Activity. I'd like a notification that says "Are you excited?", and want it to do something when I click on it. First, I'm not sure how to even add the notification here, and second I'm not sure if I add it to the service class in showNotification() method that I made up, or just say somehow if I pass the threshold, go to the mainactivity and display a button?
UPDATE: I've added my showNotification method, but not sure why it doesn't do anything. I printed a log statement for onSensorChanged() and I see it showing up in the LogCat so it is entering that method. Not sure how to make it show this notification though.

Why MainActivity cannot be resolved or is not a field?

I have a small project where I need to play with the Battery of an Android device. At first, I wanted to be able to print the Battery so I used this tutorial.
Then, I have created a new Android project called "Testing" in Eclipse, and in MainActivity.java I put this code :
package com.example.testing;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
import android.R.*;
public class MainActivity extends Activity {
TextView mTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.MainActivity); //This is the MainActivity that contains the error
mTextView = (TextView) findViewById(R.id.batterTest);
findViewById(R.id.getBattery).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mTextView.setText(String.valueOf(batteryLevel));
}
});
new Thread(new ThreadM()).start();
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mArrow);
}
BatteryReceiver mArrow;
private class ThreadM implements Runnable {
#Override
public void run() {
mArrow = new BatteryReceiver();
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction(Intent.ACTION_BATTERY_LOW);
mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
mIntentFilter.addAction(Intent.ACTION_BATTERY_OKAY);
Intent batteryIntent = registerReceiver(mArrow, mIntentFilter);
batteryLevel = getBatteryLevel(batteryIntent);
Log.e("Battery Level", String.valueOf(batteryLevel));
}
}
float batteryLevel;
private class BatteryReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
if (arg1.getAction().equalsIgnoreCase(Intent.ACTION_BATTERY_LOW) || arg1.getAction().equalsIgnoreCase(Intent.ACTION_BATTERY_CHANGED) || arg1.getAction().equalsIgnoreCase(Intent.ACTION_BATTERY_OKAY)) {
int level = arg1.getIntExtra("level", 0);
Toast.makeText(MainActivity.this,"Current Battery " + level + " %", Toast.LENGTH_LONG).show();
mTextView.setText(String.valueOf("Battery Level Change Detect through Receiver = " + level));
}
}
}
public float getBatteryLevel(Intent batteryIntent) {
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
if (level == -1 || scale == -1) {
return 50.0f;
}
return ((float) level / (float) scale) * 100.0f;
}
}
Actually this should just run a simple activity with the Battery level printed on the screen. But it does not because of one error. "MainActivity cannot be resolved or is not a field" (see the commented line).
Do you have any idea why ? I would like to have this code working so I can go on then.
Thank you.
You need to change
setContentView(R.layout.MainActivity);
to
setContentView(R.layout.activity_main);
assuming you have a layout called activity_main.xml and not MainActivity which is actually the name of your Activity class
and Remove
import android.R.*;
and import
import com.example.testing.R;

Categories