im trying to insert an handler to update the widget_textview background every x second but i dont know what and where to place
int i;
if (i==1) {
TextView myTxt = (TextView) findViewById(R.id.widget_textview);
myTxt.setBackgroundResource(R.drawable.pic1);
i++;
}else if(i==2) {
TextView myTxt = (TextView) findViewById(R.id.widget_textview);
myTxt.setBackgroundResource(R.drawable.pic2);
i++;
}else if(i==3) {
TextView myTxt = (TextView) findViewById(R.id.widget_textview);
myTxt.setBackgroundResource(R.drawable.pic1);
i=2;
}else {
i++;
}
i cant place this anywhere, everywhere i place this code i got error in textview
this is my code
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.widget.RemoteViews;
import android.widget.TextView;
public class Widget extends AppWidgetProvider {
private Handler handler = new Handler();
RemoteViews views;
AppWidgetManager appWidgetManager;
ComponentName currentWidget;
Context context;
DateFormat format = new SimpleDateFormat("HH:mm");
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
this.context = context;
this.appWidgetManager = appWidgetManager;
views = new RemoteViews(context.getPackageName(), R.layout.widget);
currentWidget = new ComponentName(context, Widget.class);
handler.removeCallbacks(UpdateWidget);
handler.postDelayed(UpdateWidget, 100);
}
final Runnable UpdateWidget = new Runnable() {
public void run() {
Intent informationIntent = new Intent(context, MainActivity.class);
PendingIntent infoPendingIntent = PendingIntent.getActivity(
context, 0, informationIntent, 0);
views.setOnClickPendingIntent(R.id.Widget, infoPendingIntent);
views.setTextViewText(R.id.widget_textview,
"" + format.format(new Date()));
appWidgetManager.updateAppWidget(currentWidget, views);
handler.postDelayed(UpdateWidget, 1000);
}
};
#Override
public void onDisabled(Context context) {
super.onDisabled(context);
handler.removeCallbacks(UpdateWidget);
}
}
put this in your handler class implementations onHandleMessage() method.This method is overridden.
public class MyHandler extends Hadnler(
onHandlerMessage(Message msg){
//your code you want to put
}
}
Related
I'm making an application that plays audio files off the device's storage, and I have a seek bar that checks the progress of the audio file (how long it has played) every second, and updates the seekbar accordingly.
The audio is played through a service that runs in the foreground, and also displays a notification that the audio is playing.
When the audio ends, I noticed the handler still goes in it's cycle, and I want to end the handler once the audio is done.
What I'm currently trying to do is to end the handler from inside the runnable that the handler runs, as I'm not sure how else I can end it.
Main Activity, where I handle OnClick from the ListView where you can select an audio file and also handles the seekbar update.
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
SeekBar musicProgBar;
Handler progBarHandler = null;
Runnable r = null;
private MP3Service.MyBinder myService = null;
TextView progressText = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
musicProgBar = findViewById(R.id.musicProgressBar);
progressText = findViewById(R.id.progressText);
final ListView lv = (ListView) findViewById(R.id.musicList);
Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
null,
MediaStore.Audio.Media.IS_MUSIC + "!= 0",
null,
null);
progBarHandler = new Handler();
final int progBarDelay = 1000; // delay for the handler, making it repeat itself only every 1000 miliseconds (1 second)
lv.setAdapter(new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
cursor,
new String[] { MediaStore.Audio.Media.DATA},
new int[] { android.R.id.text1 }));
Intent tempIntent = new Intent(this, MP3Service.class);
startService(tempIntent);
bindService(tempIntent, serviceConnection, 0);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> myAdapter,
View myView,
int myItemInt,
long myLong) {
Cursor c = (Cursor) lv.getItemAtPosition(myItemInt);
String uri = c.getString(c.getColumnIndex(MediaStore.Audio.Media.DATA));
Log.d("g53mdp", uri);
if (myService.fetchPlayerState() != MP3Player.MP3PlayerState.STOPPED)
myService.stopMusic();
myService.loadMusic(uri);
myService.playMusic();
musicProgBar.setMax(myService.fetchDuration()); // set the max value of the seekbar to be the duration of the song
r = new Runnable()
{
#Override
public void run()
{
int tempInt = myService.fetchProgress();
Log.d("progress ticking", tempInt + " " + musicProgBar.getProgress());
musicProgBar.setProgress(tempInt); // sets the current progress of the seekbar to be the progress of the song
long minutes = TimeUnit.MILLISECONDS.toMinutes(tempInt);
long seconds = TimeUnit.MILLISECONDS.toSeconds(tempInt);
if (seconds >= 60)
seconds = seconds - 60;
String tempString = minutes + ":" + seconds;
progressText.setText(tempString);
progBarHandler.postDelayed(this, progBarDelay);
if (musicProgBar.getProgress() == myService.fetchDuration())
progBarHandler.removeCallbacks(this);
}
};
progBarHandler.post(r);
}});
}
private ServiceConnection serviceConnection = new ServiceConnection()
{
#Override
public void onServiceConnected(ComponentName name, IBinder service)
{
myService = (MP3Service.MyBinder) service;
}
#Override
public void onServiceDisconnected(ComponentName name)
{
myService = null;
}
};
public void playButClicked(View view)
{
myService.playMusic();
}
public void pauseButClicked(View view)
{
myService.pauseMusic();
}
public void stopButClicked(View view)
{
myService.stopMusic();
}
#Override
protected void onDestroy()
{
unbindService(serviceConnection);
progBarHandler.removeCallbacks(r);
super.onDestroy();
}
}
What is strange is that in onDestroy(), I do use removeCallbacks to end the handler, and that works nicely. I know that it comes to the point where it calls for removeCallbacks in the Runnable r, confirmed through debugging and logging. Also tried implementing a method that is specifically for removing the handler and calling that, no luck. Also tried using return.
The part I'm struggling with is
r = new Runnable()
{
#Override
public void run()
{
int tempInt = myService.fetchProgress();
Log.d("progress ticking", tempInt + " " + musicProgBar.getProgress());
musicProgBar.setProgress(tempInt); // sets the current progress of the seekbar to be the progress of the song
long minutes = TimeUnit.MILLISECONDS.toMinutes(tempInt);
long seconds = TimeUnit.MILLISECONDS.toSeconds(tempInt);
if (seconds >= 60)
seconds = seconds % 60;
String tempString = minutes + ":" + seconds;
progressText.setText(tempString);
progBarHandler.postDelayed(this, progBarDelay);
if (musicProgBar.getProgress() == myService.fetchDuration())
progBarHandler.removeCallbacks(this);
}
};
progBarHandler.post(r);
}});
The service which handles the music player and handles playing the music
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
public class MP3Service extends Service
{
public static MP3Service instance = null; // implementing singleton by instantiating a reference to the instance
private final String SERVICE_ID = "100"; // id for the service
public static boolean isRunning = false; //
NotificationManager notificationManager = null;
int notificationID = 001;
private final IBinder binder = new MyBinder();
MP3Player mainPlayer;
#Nullable
#Override
public IBinder onBind(Intent intent)
{
return binder;
}
#Override
public void onRebind(Intent intent)
{
// TODO: implement Rebind for screen orientation change
}
#Override
public void onCreate()
{
instance = this;
isRunning = true;
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mainPlayer = new MP3Player();
super.onCreate();
Handler handler = new Handler();
}
#Override
public void onDestroy()
{
isRunning = false;
instance = null;
notificationManager.cancel(notificationID);
}
public void createNotification()
{
CharSequence name = "MP3 Notification";
String description = "Displays a notification when a song is playing";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(SERVICE_ID, name, importance);
channel.setDescription(description);
notificationManager.createNotificationChannel(channel);
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// when the user clicks the notification, this will bring them to the activity
PendingIntent navToMainActivity = PendingIntent.getActivity(this, 0, intent, 0);
// sets up the info and details for the notification
final NotificationCompat.Builder mNotification = new NotificationCompat.Builder(this, SERVICE_ID)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle("MP3 Player")
.setContentText("Playing music")
.setContentIntent(navToMainActivity)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
startForeground(notificationID, mNotification.build());
}
public void removeNotification()
{
stopForeground(false);
notificationManager.cancelAll();
}
public class MyBinder extends Binder
{
public void loadMusic(String filePath)
{
mainPlayer.load(filePath);
}
public void playMusic()
{
mainPlayer.play();
createNotification();
}
public void pauseMusic()
{
mainPlayer.pause();
removeNotification();
}
public void stopMusic()
{
mainPlayer.stop();
removeNotification();
}
public MP3Player.MP3PlayerState fetchPlayerState()
{
return mainPlayer.getState();
}
public int fetchDuration()
{
return mainPlayer.getDuration();
}
public int fetchProgress()
{
return mainPlayer.getProgress();
}
}
}
Thanks in advance for any help, and I am happy to provide with more information if required
EDIT: changed the progBarHandler.postDelay() that is outside the runnable to a simple progBarHandler.post()
I think the only reason you failed to stop the handler is constantly invoking progBarHandler.postDelayed(this, progBarDelay);,you need to check why it's still running.
Managed to get it working by introducing a different kind of if statement to the runnable, like so
Runnable r = new Runnable()
{
#Override
public void run()
{
if (musicProgBar.getProgress() == myService.fetchProgress() && myService.fetchProgress() != 0)
Log.d("audio", "over");
else {
int tempInt = myService.fetchProgress();
long minutes = TimeUnit.MILLISECONDS.toMinutes(tempInt);
long seconds = TimeUnit.MILLISECONDS.toSeconds(tempInt);
if (seconds >= 60)
seconds = seconds % 60;
String tempString = minutes + ":" + seconds;
progressText.setText(tempString);
musicProgBar.setProgress(tempInt); // sets the current progress of the seekbar to be the progress of the song
progBarHandler.postDelayed(this, progBarDelay);
}
}
};
It seemed for some reason, using .fetchDuration() and .fetchProgress() will never equalize each other, so changing the if statement worked.
I am creating an app which monitors temperature live from my SQL server. I was also creating a linegraph using MPAndroidCharts by Phil Jay and came across an issue.
I used the X-axis as a label for time(HH:mm:ss) however the time seems to update all the labels instead of only the last one. I have tried many different methods but none of them work. So I thought I would ask you guys for help. Thank You!
Image of isue here
package com.example.boiijek.myapplication;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.github.mikephil.charting.utils.ColorTemplate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import static com.example.boiijek.myapplication.SettingsActivity.PREFS_NAME;
public class MainActivity extends AppCompatActivity {
final Context context = this;
String setno, checkinglux, checkingtemp;
Button testbutton;
/**
* Created by Boiijek on 21/10/2017.
*/
TextView textalertsends, tempalertsends, luxalertsends, luxupdate, tempupdate;
BroadcastReceiver updateUIReceiver;
public static final String EXTRA_TEMP = "temp_extra";
private ArrayList<Entry> entries = new ArrayList<>();
LineChart mChart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
mChart = findViewById(R.id.chart);
XAxis xAxis = mChart.getXAxis();
xAxis.setValueFormatter(createDateFormatter());
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
mChart.getAxisLeft().setDrawGridLines(false);
mChart.getXAxis().setDrawGridLines(false);
mChart.getAxisLeft().setDrawAxisLine(false);
mChart.getXAxis().setTextColor(Color.CYAN);
mChart.getAxisLeft().setTextColor(Color.CYAN); // left y-axis
mChart.getLegend().setTextColor(Color.YELLOW);
mChart.getAxisRight().setEnabled(false);
YAxis yAxis = mChart.getAxisLeft();
yAxis = mChart.getAxisRight();
yAxis.setDrawGridLines(false);
Description description = new Description();
description.setTextColor(ColorTemplate.VORDIPLOM_COLORS[2]);
description.setText("Live Temperature Data");
mChart.setDescription(description);
setYAxisValues();
// setData();
SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
setno = settings.getString("finalno", "NULL");
checkinglux = settings.getString("checkingtemp", "99999");
checkingtemp = settings.getString("checkingtemp", "0");
textalertsends = (TextView) findViewById(R.id.textalertsends);
tempalertsends = (TextView) findViewById(R.id.tempalertsends);
luxalertsends = (TextView) findViewById(R.id.luxalertsends);
textalertsends.setText("SMS Alerts will be sent to " + setno);
tempalertsends.setText("Alerted when Temp. is over " + checkingtemp + "°C");
luxalertsends.setText("Alerted when Lux is below " + checkinglux + " lux");
testbutton = (Button) findViewById(R.id.button55);
{
if (isMyServiceRunning() == false) {
testbutton.setBackgroundColor(Color.GREEN);
testbutton.setTextColor(Color.BLACK);
testbutton.setText("Start Background Monitoring");
} else {
testbutton.setBackgroundColor(Color.RED);
testbutton.setText("Stop Background Monitoring");
}
}
testbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isMyServiceRunning() == true) {
Intent intent = new Intent(MainActivity.this, TimeService.class);
stopService(intent);
testbutton.setBackgroundColor(Color.GREEN);
testbutton.setTextColor(Color.BLACK);
testbutton.setText("Start Background Monitoring");
} else {
Intent intent = new Intent(MainActivity.this, TimeService.class);
startService(intent);
testbutton.setBackgroundColor(Color.RED);
testbutton.setText("Stop Background Monitoring");
}
}
});
IntentFilter filter = new IntentFilter();
filter.addAction("com.example.nihal.myapplication.UPDATE_DATA");
updateUIReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//UI update here
int temp = intent.getIntExtra(EXTRA_TEMP, 0);
entries.remove(0);
Calendar c = Calendar.getInstance();
int mseconds = c.get(Calendar.MILLISECOND);
entries.add(new Entry(mseconds, temp));
setData();
}
};
registerReceiver(updateUIReceiver, filter);
}
final String[] quarters = new String[] { "Q1", "Q2", "Q3", "Q4" };
IAxisValueFormatter createDateFormatter() {
IAxisValueFormatter formatter = new IAxisValueFormatter() {
#Override
public String getFormattedValue(float value, AxisBase axis) {
Date date = new Date((long) value);
SimpleDateFormat sdfDate = new SimpleDateFormat("HH:mm:ss");
Date now = new Date();
String strDate = sdfDate.format(now);
Log.d("test", strDate);
return strDate ;
}
public int getDecimalDigits() {
return 0;
}
};
return formatter;
}
private void setYAxisValues() {
entries.add(new Entry(0, 60));
entries.add(new Entry(1, 48));
entries.add(new Entry(2, 70.5f));
entries.add(new Entry(3, 100));
entries.add(new Entry(4, 180.9f));
entries.add(new Entry(5, 210f)); //test
}
private ArrayList<String> setXAxisValues() {
ArrayList<String> xVals = new ArrayList<String>();
xVals.add("10");
xVals.add("20");
xVals.add("30");
xVals.add("30.5");
xVals.add("40");
xVals.add("50"); //test
return xVals;
}
private void setData() {
ArrayList<String> xVals = setXAxisValues();
LineDataSet set1;
set1 = new LineDataSet(entries, "X Axis - Time // Y Axis - Temp");
set1.setFillAlpha(110);
set1.setColor(Color.WHITE);
set1.setCircleColor(Color.WHITE);
set1.setLineWidth(1f);
set1.setCircleRadius(3f);
set1.setDrawCircleHole(false);
set1.setValueTextSize(9f);
set1.setValueTextColor(Color.WHITE);
set1.setDrawFilled(true);
set1.setCubicIntensity(0.5f);
set1.setMode(LineDataSet.Mode.HORIZONTAL_BEZIER);
// create a data object with the datasets
LineData data = new LineData(set1);
// set data
mChart.setData(data);
mChart.invalidate();
}
public void startService(View view) {
Intent intent = new Intent(this, TimeService.class);
startService(intent);
}
public void stopService(View view) {
Intent intent = new Intent(this, TimeService.class);
stopService(intent);
}
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (TimeService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(updateUIReceiver);
}
#Override
public void onBackPressed() {
finish();
super.onBackPressed();
}
}
Add following line in your code:
mChart.setData(data);
mChart.notifyDataSetChanged(); // add this line
mChart.invalidate();
I am having a problem and I ran out of ideas how to fix it.
The goal is, when the user clicks the button an URL is loaded depending on what's selected in settings.
Problem is, I am having trouble setting it up in a right way.
Logically(to me), I tried to set it up in a service. Button is clicked > Service starts > URL is loaded from "IF ELSE".
Problem is, I get an error in "IF ELSE" - "Method length must be called from the UI Thread, currently inferred thread is is worker.
public static class Service extends IntentService {
public Service() {
super("wallpaperchanger-download");
}
#Override
protected void onHandleIntent(Intent intent) {
MainActivity mainActivity;
mainActivity = new MainActivity();
if (mainActivity.mEditTextHashtag.length() > 2) {
WallpaperManager wm = WallpaperManager.getInstance(this);
int height = wm.getDesiredMinimumHeight();
int width = wm.getDesiredMinimumWidth();
String url = "https://source.unsplash.com/all/?" + mainActivity.mEditTextHashtag.getText() + "/" + width + "x" + height + "/";
try {
InputStream input = new URL(url).openStream();
Log.v(TAG, url);
wm.setStream(input);
input.close();
} catch (Exception e) {
e.printStackTrace();
}
loading = false;
}
}
}
Ok, fair enough.
I created new Method getPhoto(); in UI Thread and put the code in there. Then, I called mainActivity.getPhoto(); in Service.
Problem is, I get an error - "Attempt to invoke virtual method 'int android.widget.EditText.length()' on a null object reference"
Any ideas on what I should do?
Full code in all its glory:
package com.edip.splashwallpaper;
import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.app.WallpaperManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.Toast;
import java.io.InputStream;
import java.net.URL;
public class MainActivity extends android.app.Activity {
final static String TAG = "AllInOne";
final static int CHANGE_INTERVAL = 30 * 1000; //30 sec for testing
static boolean loading = false;
WallpaperManager wm;
//Layout Views
Switch mSwitchFixedPhoto, mSwitchControls, mSwitchSave, mSwitchPause;
Spinner mSpinnerCategories, mSpinnerInterval;
EditText mEditTextHashtag;
Button mWallpaperButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Layout Views Initialized
mSwitchFixedPhoto = (Switch) findViewById(R.id.sw_fixedphoto);
mSwitchControls = (Switch) findViewById(R.id.switch_controls);
mSwitchSave = (Switch) findViewById(R.id.switch_save);
mSwitchPause = (Switch) findViewById(R.id.switch_pause);
mSpinnerCategories = (Spinner) findViewById(R.id.spinner_categories);
mSpinnerInterval = (Spinner) findViewById(R.id.spinner_interval);
mEditTextHashtag = (EditText) findViewById(R.id.et_hashtag);
mWallpaperButton = (Button) findViewById(R.id.btn_set_wallpaper);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapterCategory = ArrayAdapter.createFromResource(this,
R.array.categories_array, R.layout.dialog_spinner_layout);
// Specify the layout to use when the list of choices appears
adapterCategory.setDropDownViewResource(R.layout.dialog_spinner_layout);
// Apply the adapter to the spinner
mSpinnerCategories.setAdapter(adapterCategory);
ArrayAdapter<CharSequence> adapterInterval = ArrayAdapter.createFromResource(this,
R.array.interval_array, R.layout.dialog_spinner_layout);
adapterInterval.setDropDownViewResource(R.layout.dialog_spinner_layout);
mSpinnerInterval.setAdapter(adapterInterval);
mWallpaperButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PendingIntent pending = PendingIntent.getBroadcast(MainActivity.this,
666, new Intent("com.edip.splashwallpaper.CHANGE_WALLPAPTER_TIMER"),
PendingIntent.FLAG_CANCEL_CURRENT);
((AlarmManager) getSystemService(Context.ALARM_SERVICE))
.setRepeating(AlarmManager.RTC, System.currentTimeMillis(),
CHANGE_INTERVAL, pending);
}
});
}
public void getPhoto() {
if (mEditTextHashtag.length() > 2) {
wm = WallpaperManager.getInstance(this);
int height = wm.getDesiredMinimumHeight();
int width = wm.getDesiredMinimumWidth();
String url = "https://source.unsplash.com/all/?" + mEditTextHashtag.getText() + "/" + width + "x" + height + "/";
try {
InputStream input = new URL(url).openStream();
Log.v(TAG, url);
wm.setStream(input);
input.close();
} catch (Exception e) {
e.printStackTrace();
}
loading = false;
} else {
Toast.makeText(this, "Something else", Toast.LENGTH_SHORT).show();
}
}
public static class Service extends IntentService {
public Service() {
super("wallpaperchanger-download");
}
#Override
protected void onHandleIntent(Intent intent) {
MainActivity mainActivity;
mainActivity = new MainActivity();
mainActivity.getPhoto();
}
}
public static class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
if (!loading) {
loading = true;
context.startService(new Intent(context, Service.class));
}
}
}
}
Thanks :)
First of all, you should never instantiate an activity by yourself.
Second, as a best practice, your service shouldn't know about your activity, or that it has an edit text. Instead you should send the URL to load inside your intent, when the PendingIntent is created, like this :
Intent intent = new Intent("com.edip.splashwallpaper.CHANGE_WALLPAPTER_TIMER");
intent.putExtra("USER_URL", "https://source.unsplash.com/all/?" + mEditTextHashtag.getText() + "/" + width + "x" + height + "/");
PendingIntent pending = PendingIntent.getBroadcast(MainActivity.this,
666, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Then within your service, read the url like so :
#Override
protected void onHandleIntent(Intent intent) {
String url = intent.getStringExtra("USER_URL");
// ...
}
I am trying to make an app in which there is a lock / password screen before you open selected apps to protect your apps.
There are some on the market such as:
https://play.google.com/store/apps/details?id=com.domobile.applock&hl=en
Here is an open source one on GitHub. https://github.com/twinone/AppLocker
I realized that even if the above apps are killed, or ram the is cleared, or the phone is restarted etc. The lock screen stills shows up for the selected application.
Essentially I want to achieve the same thing that they did, but currently I am not achieving this currently with the service class I have written. I can lock the app, but when the app is killed I cannot. I have spent a great deal of time learning pending intents, alarm managers, broadcast receivers, and even studying example source code
https://github.com/twinone/AppLocker/blob/master/src/com/twinone/locker/lock/AppLockService.java
but I am not successful in my implementation.
Here is my service class:
package com.ibc.android.demo.appslist.app;
import android.app.ActivityManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.util.Log;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
public class HeartBeat extends Service {
private static final String TAG = HeartBeat.class.getSimpleName();
public Timer TIMER;
private static Set<AccessGranted> mAccessGrantedList = new HashSet<AccessGranted>();
private Set<String> mLockedApps = new HashSet<String>();
private long lastModified = 0;
private BroadcastReceiver mScreenStateReceiver;
private BroadcastReceiver mAccessGrantedReceiver;
private File mLockedAppsFile;
ArrayList<String> packagezList;
SharedPreferences sharedPrefs;
Map<String, ?> allEntries;
SharedPreferences sharedPrefsapp;
String prefix;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startService(new Intent(this, HeartBeat.class));
// Log.i("LocalService", "Received start id " + startId + ": " +
// intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
if (TIMER == null) {
TIMER = new Timer(true);
TIMER.scheduleAtFixedRate(new LockAppsTimerTask(), 1000, 250);
mScreenStateReceiver = new BroadcastReceiver() {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
if (screenOff) {
//Log.i(TAG, "Cancel Timer");
TIMER.cancel();
} else {
// Log.i(TAG, "Restart Timer");
TIMER = new Timer(true);
TIMER.scheduleAtFixedRate(new LockAppsTimerTask(), 1000, 250);
}
}
};
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mScreenStateReceiver, filter);
mAccessGrantedReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
String packageName = intent.getStringExtra("packageName");
if (action.equals(Constants.ACTION_GRANT_ACCESS) && packageName != null) {
AccessGranted ag = new AccessGranted(packageName);
mAccessGrantedList.remove(ag);
mAccessGrantedList.add(ag);
}
}
};
IntentFilter filter2 = new IntentFilter(Constants.ACTION_GRANT_ACCESS);
registerReceiver(mAccessGrantedReceiver, filter2);
}
// this.stopSelf();
//startforeground goes here
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
startService(new Intent(this, HeartBeat.class));
}
private class LockAppsTimerTask extends TimerTask {
#Override
public void run() {
sharedPrefs = getApplicationContext().getSharedPreferences(getApplicationContext().getPackageName(), Context.MODE_PRIVATE);
sharedPrefsapp = getApplicationContext().getSharedPreferences("appdb", Context.MODE_PRIVATE);
allEntries= null;
allEntries = sharedPrefsapp.getAll();
//prefix = "m";
packagezList= null;
packagezList = new ArrayList<String>();
for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
//Log.e("right key: ", entry.getKey() + "right value: " + entry.getValue().toString() );
packagezList.add(entry.getKey());
}
/* for (Map.Entry<String, ?> entry : allEntries.entrySet())
{
//Check if the package name starts with the prefix.
if (entry.getKey().startsWith(prefix)) {
//Add JUST the package name (trim off the prefix).
packagezList.add(entry.getKey().substring(prefix.length()));
packagezList.add(entry.getKey());
}
}*/
for(Object object: packagezList){
Log.e("YO!", (String) object);
}
ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
try {
//List<RecentTaskInfo> recentTasks = activityManager.getRecentTasks(1, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> RunningTask = mActivityManager
.getRunningTasks(1);
ActivityManager.RunningTaskInfo ar = RunningTask.get(0);
String activityOnTop = ar.topActivity.getPackageName();
// Log.e("activity on Top", "" + activityOnTop);
// Log.e(" My package name", "" + getApplicationContext().getPackageName());
//for (Object data : newArrayList) {
for(Object object: packagezList){
// Provide the packagename(s) of apps here, you want to show password activity
if ((activityOnTop.contains((CharSequence) object)) &&
(!activityOnTop.contains(getApplicationContext().getPackageName()
))) { // you have to make this check even better
Intent i = new Intent(getApplicationContext(), LockScreenActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
i.putExtra( "", "");
startActivity(i);
}
}
} catch (Exception e) {
// Log.e("Foreground App", e.getMessage(), e);
}
}
}
}
Here is my LockScreen activity class (the screen that is displayed when the selected app is open) :
package com.ibc.android.demo.appslist.app;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import com.spicycurryman.getdisciplined10.app.R;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class LockScreenActivity extends Activity {
private static final String TAG = LockScreenActivity.class.getSimpleName();
Map<String, ?> allEntries;
SharedPreferences sharedPrefsapp;
ArrayList<String> packagezList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setup);
}
#Override
public void onBackPressed() {
// Grab a list of all running processes and their PIDs.
ActivityManager am = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> pids = am.getRunningAppProcesses();
// Now loop through the list of PIDs and find Instagram's PID.
sharedPrefsapp = getApplicationContext().getSharedPreferences("appdb", Context.MODE_PRIVATE);
allEntries= null;
allEntries = sharedPrefsapp.getAll();
//prefix = "m";
packagezList= null;
packagezList = new ArrayList<String>();
for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
//Log.e("right key: ", entry.getKey() + "right value: " + entry.getValue().toString() );
packagezList.add(entry.getKey());
}
// Killing any process for blocked applications when the back button is pressed while the lock screen is displayed
for(Object object: packagezList){
am.killBackgroundProcesses((String) object);
Log.d("Killed Background Process!: ", (String) object);
}
// Now that we've got the PID, kill the Instagram process.
// Now that we've got the PID, kill the Instagram process.
ActivityManager am1 = (ActivityManager) getApplicationContext().getSystemService(ACTIVITY_SERVICE);
// Display confirmation here, finish() activity.
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
startService(new Intent(this, HeartBeat.class));
/* Intent iHeartBeatService = new Intent(this, HeartBeat.class);
PendingIntent piHeartBeatService = PendingIntent.getService(this, 0, iHeartBeatService, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(piHeartBeatService);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 300000, piHeartBeatService);*/
finish();
super.onBackPressed();
}
}
Right now I am able to lock the apps, but when the app is killed or phone is restarted I cannot. The app lock apps on the Google Play Store can successfully still lock apps with a pin when all apps are force stopped or when the phone is restarted, ram cleared, etc.
How can I achieve this like those have?
I think u should try this ...
package com.ankit.vkapplock;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class StartupServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
context.startService(new Intent(context, HeartBeat.class ));
}
Dont forget to add permisson for boot_completion action.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
I made two activities, one for the widget and one for the settings activity.
There are two variables "strSavedMem1" & "strSavedMem1" initialised in the settings activity... and are made via sharedPreference method.
But when I try to use the variable in widget activity, the variable return a "null" value.
The widget Activity:
package com.eightbitcloud.example.widget;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.RemoteViews;
import com.shashank.pingwidget.R;
public class ExampleAppWidgetProvider extends AppWidgetProvider {
private static final String LOG_TAG = "Ping_Widget";
private static Handler handler;
static String currentTime = null ;
public String strSavedMem1;
public String strSavedMem2;
public static final String PREFS_NAME="LocalePrefs";
/**
* Custom Intent name that is used by the AlarmManager to tell us to update the clock once per second.
*/
public static String PING_WIDGET_UPDATE = "com.eightbitcloud.example.widget.8BITCLOCK_WIDGET_UPDATE";
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (PING_WIDGET_UPDATE.equals(intent.getAction())) {
Log.d(LOG_TAG, "Clock update");
// Get the widget manager and ids for this widget provider, then call the shared
// clock update method.
ComponentName thisAppWidget = new ComponentName(context.getPackageName(), getClass().getName());
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int ids[] = appWidgetManager.getAppWidgetIds(thisAppWidget);
for (int appWidgetID: ids) {
updateAppWidget(context, appWidgetManager, appWidgetID);
}
}
}
private PendingIntent createClockTickIntent(Context context) {
Intent intent = new Intent(PING_WIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
#Override
public void onDisabled(Context context) {
super.onDisabled(context);
Log.d(LOG_TAG, "Widget Provider disabled. Turning off timer");
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(createClockTickIntent(context));
}
#Override
public void onEnabled(Context context) {
super.onEnabled(context);
SharedPreferences sharedPreferences = context.getSharedPreferences(PREFS_NAME,0);
strSavedMem1 = sharedPreferences.getString("MEM1", null);
if (strSavedMem1 == null) {
strSavedMem1="google.com";
Log.d(getClass().getSimpleName(),"MEM1 name is: "+ strSavedMem1);
}
strSavedMem2 = sharedPreferences.getString("MEM1", null);
if (strSavedMem2 == null) {
strSavedMem2 = "1";
Log.d(getClass().getSimpleName(),"MEM2 name is: "+ strSavedMem2);
}
Log.d(LOG_TAG, "Widget Provider enabled. Starting timer to update widget every second");
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 30);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), 50000, createClockTickIntent(context));
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
Log.d(LOG_TAG, "Updating Example Widgets.");
// Perform this loop procedure for each App Widget that belongs to this
// provider
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
// Create an Intent to launch ExampleActivity
Intent intent = new Intent(context, WidgetExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
// Get the layout for the App Widget and attach an on-click listener
// to the button
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget1);
views.setOnClickPendingIntent(R.id.button, pendingIntent);
// Tell the AppWidgetManager to perform an update on the current app
// widget
appWidgetManager.updateAppWidget(appWidgetId, views);
// Update The clock label using a shared method
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
public void updateAppWidget(final Context context, final AppWidgetManager appWidgetManager, final int appWidgetId) {
//String currentTime = df.format(new Date());
handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
String pingCmd = "ping -c 3 " + "google.com";
String pingResult = "";
Runtime r = Runtime.getRuntime();
Process p = r.exec(pingCmd);
BufferedReader in = new BufferedReader(new
InputStreamReader(p.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
currentTime = inputLine + "\n";
pingResult += inputLine+ "\n";
currentTime = pingResult ;
}
in.close();
}//try
catch (IOException e) {
System.out.println(e);
}
handler.post(new Runnable() {
#Override
public void run() {
//progress.setProgress(value);
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.widget1);
updateViews.setTextViewText(R.id.widget1label, currentTime+"\n"+ strSavedMem1+"\n"+strSavedMem2);
appWidgetManager.updateAppWidget(appWidgetId, updateViews);
}
});
}
};
new Thread(runnable).start();
}
}
The settings activity is:
package com.eightbitcloud.example.widget;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.shashank.pingwidget.R;
public class WidgetExampleActivity extends Activity {
public static final String PREFS_NAME="LocalePrefs";
public Context ctx = null;
EditText editText1, editText2;
TextView textSavedMem1, textSavedMem2;
Button buttonSaveMem1, buttonSaveMem2;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textSavedMem1 = (TextView)findViewById(R.id.savedmem1);
textSavedMem2 = (TextView)findViewById(R.id.savedmem2);
editText1 = (EditText)findViewById(R.id.edittext1);
editText2 = (EditText)findViewById(R.id.edittext2);
buttonSaveMem1 = (Button)findViewById(R.id.save_mem1);
buttonSaveMem2 = (Button)findViewById(R.id.save_mem2);
buttonSaveMem1.setOnClickListener(buttonSaveMem1OnClickListener);
buttonSaveMem2.setOnClickListener(buttonSaveMem2OnClickListener);
LoadPreferences();
}
Button.OnClickListener buttonSaveMem1OnClickListener
= new Button.OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
SavePreferences("MEM1", editText1.getText().toString());
LoadPreferences();
}
};
Button.OnClickListener buttonSaveMem2OnClickListener = new Button.OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
SavePreferences("MEM2", editText2.getText().toString());
LoadPreferences();
}
};
private void SavePreferences(String key, String value){
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME,MODE_WORLD_READABLE);
/*SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();*/
//SharedPreferences sharedPreferences =PreferenceManager.getDefaultSharedPreferences(WidgetExampleActivity.this);
//SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_WORLD_READABLE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
}
public void LoadPreferences(){
// SharedPreferences sharedPreferences = ctx.getSharedPreferences(PREFS_NAME, MODE_WORLD_READABLE);
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_WORLD_READABLE);
String strSavedMem1 = sharedPreferences.getString("MEM1", "google.com");
String strSavedMem2 = sharedPreferences.getString("MEM2", "1");
textSavedMem1.setText(strSavedMem1);
textSavedMem2.setText(strSavedMem2);
strSavedMem1 = sharedPreferences.getString("MEM1", null);
if (strSavedMem1 == null) {
strSavedMem1="google.com";
Log.d(getClass().getSimpleName(),"Wallpaper name is: "+ strSavedMem1);
}
strSavedMem2 = sharedPreferences.getString("MEM1", null);
if (strSavedMem2 == null) {
strSavedMem2 = "1";
Log.d(getClass().getSimpleName(),"Wallpaper name is: "+ strSavedMem2);
}
}
}
You should
check if the commit worked and returned true.
open both SharedPreferences in the same way using MODE_PRIVATE (as a constant and not its value)