Please Share code in answers if possible
Here is My code, basically I think my app is not responding after sometime maybe because the freezing gui and high memory usage, It is using even 16.8 MB of memory while in background. Please share some tips by which I can make my app simple and fast without losing functionality.
StopWatch.java
package com.study.meter;
import android.app.Service;
import android.os.IBinder;
import android.content.Intent;
import android.widget.Toast;
import android.os.Handler;
import java.util.Locale;
import android.app.PendingIntent;
import androidx.core.app.NotificationCompat;
import android.app.NotificationManager;
import android.app.Notification;
import android.content.Context;
public class StopWatch extends Service{
public static StopWatch getStopWatch;
public static int StopWatchSecs;
public static boolean isStopWatchRunning = false;
public static boolean isRunning;
public String StopWatchTime;
private NotificationCompat.Builder builder;
private Intent notificationIntent;
private PendingIntent contentIntent;
private Notification notificaton;
private NotificationManager manager;
private String StopWatchNotificationText,StopWatchNotificationTitle;
#Override
public int onStartCommand (Intent intent, int flags, int startId)
{
return START_CONTINUATION_MASK;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
getStopWatch = this;
}
#Override
public void onDestroy() {
isRunning = false;
Toast.makeText(getBaseContext(),"Destroyed",Toast.LENGTH_SHORT).show();
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startid) {
super.onStart(intent,startid);
isRunning = true;
}
public Handler StopWatchHandler = new Handler();
public Runnable StopWatchRunnable = new Runnable()
{
#Override
public void run()
{
StopWatchSecs++;
int seconds = StopWatchSecs;
int hours = seconds / 3600;
int minutes = (seconds % 3600) / 60;
int secs = seconds % 60;
// Format the seconds into hours, minutes,
// and seconds.
StopWatchTime
= String
.format(Locale.getDefault(),
"%d:%02d:%02d", hours,
minutes, secs);
// if app is running then change counting
if(MainActivity.Stop_Watch!=null && MainActivity.isAppRunning)
{
// Set the text view text.
MainActivity.Stop_Watch.setText(StopWatchTime);
}
addStopWatchNotification("StopWatch",StopWatchTime);
StopWatchHandler.postDelayed(StopWatchRunnable,1000);
}
};
public void Start_Watch()
{
StopWatchHandler.post(StopWatchRunnable);
}
public void Stop_Watch()
{
StopWatchHandler.removeCallbacks(StopWatchRunnable);
}
public String Start_Or_Stop_Watch()
{
String result = "Start";
if(isStopWatchRunning)
{
result = "Resume";
isStopWatchRunning = false;
Stop_Watch();
}
else if(!isStopWatchRunning)
{
result = "Pause";
isStopWatchRunning = true;
Start_Watch();
}
return result;
}
// adding new Handler for notifications to not overload memory
public Handler StopWatchNotificationHandler = new Handler();
public Runnable StopWatchNotificationRunnable;
public void addStopWatchNotification(String title,String text)
{
if(builder==null)
{
builder = new NotificationCompat.Builder(this);
builder
.setSmallIcon(R.drawable.notify_icon)
.setAutoCancel(false)
.setOnlyAlertOnce(true);
}
if(notificationIntent==null)
{
notificationIntent = new Intent(this, MainActivity.class);
}
if(contentIntent==null)
{
contentIntent = PendingIntent.getActivity(this, 0, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
}
if(manager==null)
{
manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
if(StopWatchNotificationRunnable==null)
{
StopWatchNotificationRunnable = new Runnable()
{
#Override
public void run()
{
builder
.setContentTitle(title)
.setContentText(text);
notificaton = builder.build();
notificaton.flags |= Notification.FLAG_NO_CLEAR;
manager.notify(0, notificaton);
}
};
}
StopWatchNotificationText = text;
StopWatchNotificationTitle = title;
StopWatchNotificationHandler.post(StopWatchNotificationRunnable);
}
}
MainActivity.java
package com.study.meter;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.content.Context;
public class MainActivity extends AppCompatActivity
{
public static boolean isAppRunning;
public static TextView Stop_Watch;
public static MainActivity activity;
public Button Start_Watch;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// set content view
setContentView(R.layout.activity_main);
// hide statusbar
getSupportActionBar().hide();
activity = this;
// set the value of StopWatch
Stop_Watch = findViewById(R.id.StopWatch);
Start_Watch = findViewById(R.id.StartWatch);
//if StopWatch service is not running
if(!StopWatch.isRunning)
{
// start the service
startService(new Intent(this, StopWatch.class));
}
}
#Override
public void onResume()
{
super.onResume();
isAppRunning = true;
if(StopWatch.StopWatchSecs!=0)
{
// if stopwatchsecs is not equal to null or 0
if(StopWatch.isStopWatchRunning)
{
// if stopwatch is running in background
Start_Watch.setText("Pause");
}else
{
// if stopwatch is not running in background
Start_Watch.setText("Resume");
}
}
}
#Override
public void onPause()
{
isAppRunning = false;
super.onPause();
}
// "StartWatch" click
public void StartorStop(View v)
{
Button sv = (Button)v;
String StartWatchText = StopWatch.getStopWatch.Start_Or_Stop_Watch();
sv.setText(StartWatchText);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.study.meter"
android:installLocation="auto">
<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.StudyMeter">
<service
android:name=".StopWatch"
android:stopWithTask="false"/>
<activity android:name=".MainActivity"
android:configChanges="orientation|screenSize|screenLayout">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/StopWatch"
android:textSize="65dp"
android:text="0:00:00"
app:layout_constraintBottom_toTopOf="#id/StartWatch"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:layout_height="50dp"
android:layout_width="wrap_content"
android:id="#+id/StartWatch"
android:text="Start"
android:onClick="StartorStop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/StopWatch"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Seems like an architecture problem, try to modulate more your Java code by dividing it in more activities, too much tasks in few activities causes crashes and poor performance ;)
Related
The thing is I want to write an app to capture audio and process it in the background with foreground service, start with a button on MainActivity and it's here.
I want to add the ability to take a screenshot, I've found this question, through which I found the example here.This template uses mediaproject to do it and whenever I press the icon to start it my MainActivity doesn't show up that the app will start running In the background, right.
Is there any other way to start screenshot from button on MainActivity(or how to continuous shooting screen),If possible I can completely capture the screen continuously.
PS:I searched but still don't know where to do it is probably because of using onActivityResult,
Here is the code that capture screen with mediaproject:
MainActivity.java
package com.commonsware.android.andshooter;
import android.app.Activity;
import android.content.Intent;
import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
public class MainActivity extends Activity {
private static final int REQUEST_SCREENSHOT=59706;
private MediaProjectionManager mgr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mgr=(MediaProjectionManager)getSystemService(MEDIA_PROJECTION_SERVICE);
startActivityForResult(mgr.createScreenCaptureIntent(),
REQUEST_SCREENSHOT);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode==REQUEST_SCREENSHOT) {
if (resultCode==RESULT_OK) {
Intent i=
new Intent(this, ScreenshotService.class)
.putExtra(ScreenshotService.EXTRA_RESULT_CODE, resultCode)
.putExtra(ScreenshotService.EXTRA_RESULT_INTENT, data);
startService(i);
}
}
finish();
}
}
ImageTransmogrifier.java
package com.commonsware.android.andshooter;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.media.Image;
import android.media.ImageReader;
import android.view.Display;
import android.view.Surface;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
public class ImageTransmogrifier implements ImageReader.OnImageAvailableListener {
private final int width;
private final int height;
private final ImageReader imageReader;
private final ScreenshotService svc;
private Bitmap latestBitmap=null;
ImageTransmogrifier(ScreenshotService svc) {
this.svc=svc;
Display display=svc.getWindowManager().getDefaultDisplay();
Point size=new Point();
display.getRealSize(size);
int width=size.x;
int height=size.y;
while (width*height > (2<<19)) {
width=width>>1;
height=height>>1;
}
this.width=width;
this.height=height;
imageReader=ImageReader.newInstance(width, height,
PixelFormat.RGBA_8888, 2);
imageReader.setOnImageAvailableListener(this, svc.getHandler());
}
#Override
public void onImageAvailable(ImageReader reader) {
final Image image=imageReader.acquireLatestImage();
if (image!=null) {
Image.Plane[] planes=image.getPlanes();
ByteBuffer buffer=planes[0].getBuffer();
int pixelStride=planes[0].getPixelStride();
int rowStride=planes[0].getRowStride();
int rowPadding=rowStride - pixelStride * width;
int bitmapWidth=width + rowPadding / pixelStride;
if (latestBitmap == null ||
latestBitmap.getWidth() != bitmapWidth ||
latestBitmap.getHeight() != height) {
if (latestBitmap != null) {
latestBitmap.recycle();
}
latestBitmap=Bitmap.createBitmap(bitmapWidth,
height, Bitmap.Config.ARGB_8888);
}
latestBitmap.copyPixelsFromBuffer(buffer);
image.close();
ByteArrayOutputStream baos=new ByteArrayOutputStream();
Bitmap cropped=Bitmap.createBitmap(latestBitmap, 0, 0,
width, height);
cropped.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] newPng=baos.toByteArray();
svc.processImage(newPng);
}
}
Surface getSurface() {
return(imageReader.getSurface());
}
int getWidth() {
return(width);
}
int getHeight() {
return(height);
}
void close() {
imageReader.close();
}
}
ScreenshotService.java
package com.commonsware.android.andshooter;
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.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.AudioManager;
import android.media.MediaScannerConnection;
import android.media.ToneGenerator;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.view.WindowManager;
import java.io.File;
import java.io.FileOutputStream;
public class ScreenshotService extends Service {
private static final String CHANNEL_WHATEVER="channel_whatever";
private static final int NOTIFY_ID=9906;
static final String EXTRA_RESULT_CODE="resultCode";
static final String EXTRA_RESULT_INTENT="resultIntent";
static final String ACTION_RECORD=
BuildConfig.APPLICATION_ID+".RECORD";
static final String ACTION_SHUTDOWN=
BuildConfig.APPLICATION_ID+".SHUTDOWN";
static final int VIRT_DISPLAY_FLAGS=
DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY |
DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
private MediaProjection projection;
private VirtualDisplay vdisplay;
final private HandlerThread handlerThread=
new HandlerThread(getClass().getSimpleName(),
android.os.Process.THREAD_PRIORITY_BACKGROUND);
private Handler handler;
private MediaProjectionManager mgr;
private WindowManager wmgr;
private ImageTransmogrifier it;
private int resultCode;
private Intent resultData;
final private ToneGenerator beeper=
new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
#Override
public void onCreate() {
super.onCreate();
mgr=(MediaProjectionManager)getSystemService(MEDIA_PROJECTION_SERVICE);
wmgr=(WindowManager)getSystemService(WINDOW_SERVICE);
handlerThread.start();
handler=new Handler(handlerThread.getLooper());
}
#Override
public int onStartCommand(Intent i, int flags, int startId) {
if (i.getAction()==null) {
resultCode=i.getIntExtra(EXTRA_RESULT_CODE, 1337);
resultData=i.getParcelableExtra(EXTRA_RESULT_INTENT);
foregroundify();
}
else if (ACTION_RECORD.equals(i.getAction())) {
if (resultData!=null) {
startCapture();
}
else {
Intent ui=
new Intent(this, MainActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(ui);
}
}
else if (ACTION_SHUTDOWN.equals(i.getAction())) {
beeper.startTone(ToneGenerator.TONE_PROP_NACK);
stopForeground(true);
stopSelf();
}
return(START_NOT_STICKY);
}
#Override
public void onDestroy() {
stopCapture();
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
throw new IllegalStateException("Binding not supported. Go away.");
}
WindowManager getWindowManager() {
return(wmgr);
}
Handler getHandler() {
return(handler);
}
void processImage(final byte[] png) {
new Thread() {
#Override
public void run() {
File output=new File(getExternalFilesDir(null),
"screenshot.png");
try {
FileOutputStream fos=new FileOutputStream(output);
fos.write(png);
fos.flush();
fos.getFD().sync();
fos.close();
MediaScannerConnection.scanFile(ScreenshotService.this,
new String[] {output.getAbsolutePath()},
new String[] {"image/png"},
null);
}
catch (Exception e) {
Log.e(getClass().getSimpleName(), "Exception writing out screenshot", e);
}
}
}.start();
beeper.startTone(ToneGenerator.TONE_PROP_ACK);
stopCapture();
}
private void stopCapture() {
if (projection!=null) {
projection.stop();
vdisplay.release();
projection=null;
}
}
private void startCapture() {
projection=mgr.getMediaProjection(resultCode, resultData);
it=new ImageTransmogrifier(this);
MediaProjection.Callback cb=new MediaProjection.Callback() {
#Override
public void onStop() {
vdisplay.release();
}
};
vdisplay=projection.createVirtualDisplay("andshooter",
it.getWidth(), it.getHeight(),
getResources().getDisplayMetrics().densityDpi,
VIRT_DISPLAY_FLAGS, it.getSurface(), null, handler);
projection.registerCallback(cb, handler);
}
private void foregroundify() {
NotificationManager mgr=
(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O &&
mgr.getNotificationChannel(CHANNEL_WHATEVER)==null) {
mgr.createNotificationChannel(new NotificationChannel(CHANNEL_WHATEVER,
"Whatever", NotificationManager.IMPORTANCE_DEFAULT));
}
NotificationCompat.Builder b=
new NotificationCompat.Builder(this, CHANNEL_WHATEVER);
b.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL);
b.setContentTitle(getString(R.string.app_name))
.setSmallIcon(R.mipmap.ic_launcher)
.setTicker(getString(R.string.app_name));
b.addAction(R.drawable.ic_record_white_24dp,
getString(R.string.notify_record),
buildPendingIntent(ACTION_RECORD));
b.addAction(R.drawable.ic_eject_white_24dp,
getString(R.string.notify_shutdown),
buildPendingIntent(ACTION_SHUTDOWN));
startForeground(NOTIFY_ID, b.build());
}
private PendingIntent buildPendingIntent(String action) {
Intent i=new Intent(this, getClass());
i.setAction(action);
return(PendingIntent.getService(this, 0, i, 0));
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.commonsware.android.andshooter"
xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name">
<activity
android:name=".MainActivity"
android:theme="#style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".ScreenshotService"
android:exported="true" />
</application>
</manifest>
In my application I simply copy the ScreenshotService ImageTransmogrifier file then run it from MainActivity as above.
Working on an app that is supposed to generate random characters via a broadcast. I need to broadcast the random characters generated by my custom service, so that the main activity registered to intercept the broadcast can get the random numbers and display them on an EditText. The layout is shown here: app layout
The start button will trigger the random character generator service. The EditText will display the random numbers generated in real time (without any button press). The stop button will stop the service. The EditText won’t display any numbers. I have created a service(RandomCharacterService) and registered it in my manifest. Upon running the app, my app crashes. I am sure it is because I did not register my broadcast in my manifest, but I do not understand how to do that. And perhaps there is something wrong with how I am handling the broadcast in my main activity. In my button click method for the start button, I tried to do a for-loop, but this resulted in the app crashing as well.
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.cs7455rehmarazzaklab8">
<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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".RandomCharacterService"></service>
</application>
MainActivityjava:
package com.example.cs7455rehmarazzaklab8;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.support.constraint.ConstraintLayout;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.Toast;
import java.util.Random;
public class MainActivity extends AppCompatActivity
{
private Button btnStart, btnStop;
private EditText myTV;
private Intent serviceIntent;
private RandomCharacterService myService;
private ServiceConnection myServiceConnection;
private boolean isServiceOn; //checks if the service is on
private int myRandomCharacter;
char MyRandomCharacter = (char)myRandomCharacter;
private boolean isRandomGeneratorOn;
private final int MIN = 65;
char m = (char)MIN;
private final int MAX = 26;
char x = (char)MAX;
private final String TAG = "Random Char Service: ";
private final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private Context mContext;
private Random mRandom = new Random();
// Initialize a new BroadcastReceiver instance
private BroadcastReceiver mRandomCharReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent) {
// Get the received random number
myRandomCharacter = intent.getIntExtra("RandomCharacter",-1);
// Display a notification that the broadcast received
Toast.makeText(context,"Received : " + myRandomCharacter,Toast.LENGTH_SHORT).show();
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
requestWindowFeature(Window.FEATURE_ACTION_BAR);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get the application context
mContext = getApplicationContext();
btnStart = (Button) findViewById(R.id.StartButton);
btnStop = (Button) findViewById(R.id.StopButton);
myTV = (EditText)findViewById(R.id.RandomCharText);
// Register the local broadcast
LocalBroadcastManager.getInstance(mContext).registerReceiver(mRandomCharReceiver, new IntentFilter("BROADCAST_RANDOM_CHARACTER"));
// Change the action bar color
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#FFFF00BF")));
// Set a click listener for start button
btnStart.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
isServiceOn = true;
serviceIntent = new Intent(getApplicationContext(), RandomCharacterService.class);
startService(serviceIntent);
setRandomNumber();
// Generate a random char
myRandomCharacter = new Random().nextInt(x)+m;
// Initialize a new intent instance
Intent intent = new Intent("BROADCAST_RANDOM_CHARACTER");
// Put the random character to intent to broadcast it
intent.putExtra("RandomCharacter",myRandomCharacter);
// Send the broadcast
LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
// Update the TextView with random character
myTV.setText(" " + myRandomCharacter );
}
});
btnStop.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
isServiceOn = false;
stopService(serviceIntent);
}
});
}
private void setRandomNumber()
{
myTV.setText("Random Character: " + (char)myService.getRandomCharacter());
String alphabet = myTV.getText().toString();
}
}
RandomCharacterService.java:
package com.example.cs7455rehmarazzaklab8;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.util.Log;
import java.util.Random;
public class RandomCharacterService extends Service
{
private int myRandomCharacter;
char MyRandomCharacter = (char)myRandomCharacter;
private boolean isRandomGeneratorOn;
private final int MIN = 65;
char m = (char)MIN;
private final int MAX = 26;
char x = (char)MAX;
private final String TAG = "Random Char Service: ";
private final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
class RandomCharacterServiceBinder extends Binder{
public RandomCharacterService getService()
{
return RandomCharacterService.this;
}
}
private IBinder myBinder = new RandomCharacterServiceBinder();
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.i(TAG, "In OnStartCommand Thread ID is "+Thread.currentThread().getId());
isRandomGeneratorOn = true;
new Thread(new Runnable()
{
#Override
public void run()
{
startRandomGenerator();
}
}
).start();
return START_STICKY;
}
private void startRandomGenerator()
{
while(isRandomGeneratorOn)
{
char alphabet = 'A';
for (int i = 65; i < 90; i++)
{
try
{
Thread.sleep(1000);
if(isRandomGeneratorOn)
{
alphabet++;
myRandomCharacter = new Random().nextInt(x)+m;
Log.i(TAG, "Thread ID is "+Thread.currentThread().getId() + ", Random character is "+(char)myRandomCharacter);
}
}
catch(InterruptedException e)
{
Log.i(TAG, "Thread Interrupted.");
}
}
}
}
private void stopRandomGenerator()
{
isRandomGeneratorOn = false;
}
public int getRandomCharacter()
{
return myRandomCharacter;
}
public boolean isRandomGeneratorOn() {
return isRandomGeneratorOn;
}
#Override
public void onDestroy()
{
super.onDestroy();
stopRandomGenerator();
Log.i(TAG, "Service Destroyed.");
}
#Nullable
#Override
public IBinder onBind(Intent intent)
{
Log.i(TAG, "In onBind ...");
return myBinder;
}
}
Call Stack:callstack from running the app
Call Stack from attempting to press the stop button:crash from attempting to press stop button
Since you are using the bound service (using Ibinder). You will have to start the service by calling bindService instead of startService. But before that you need to initialize your ServiceConnection variable and better use the isServiceOn boolean as in the below example.
private ServiceConnection myServiceConnection = new ServiceConnection() {
#Override
// IBinder interface is through which we receive the service object for communication.
public void onServiceConnected(ComponentName name, IBinder binder) {
RandomCharacterServiceBinder myBinder = (RandomCharacterServiceBinder) binder;
isServiceOn = true;
myService = myBinder.getService();
Toast.makeText(context,"Service connected", Toast.LENGTH_SHORT).show();
}
#Override
public void onServiceDisconnected(ComponentName name) {
isServiceOn = false;
myService = null;
}
};
After onServiceConnected is called, you will get your service object. Most probably your service will be initialized before you perform a click. But just to ensure you can TOAST some message within it.
And you should start the service in Activity's onCreate method, so service will get some time in creation. So move the below code from you click listener to onCreate method.
serviceIntent = new Intent(getApplicationContext(), RandomCharacterService.class);
// startService(serviceIntent); <-- remove this line, call bindService
bindService(intent, myServiceConnection, Context.BIND_AUTO_CREATE);
and wait for the service connection Toast to appear.
My goal is to have UDP packets receiving app continuously running from boot up in the back ground when ever it receives the valid packet it has to process the message and display them.
After some research, I did the following.
Broadcast Receiver class - which start the service on boot UP (mstart.java).
Service Class to monitor for UDP packets (udp.java).
Display Class to display the messages as text (Rmsgs.java).
GlobalState.Java for Global variable.
I wrote a standalone with UDP app with list view it works fine. Hence, I know there is no problem on that.
When I compiled ran the code service start on boot and then crashes. To debug I have taken away the UDP Packet receiving part. The UDP class after receiving the packets it will produce two arrays list and will save it in the Global class and the Display class will obtain it.
This code is working now, I found mistake I have made and corrected it.
Now I have to modify to receive the udp packets.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.QUICKBOOT_POWERON"/>
<application
android:name="com.mmm.rmsg.GlobalState"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:theme="#style/AppTheme" >
<activity
android:name=".MsgView"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:enabled="true" android:exported="true"
android:name=".mstart"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service android:name=".udp"
/>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
Broadcast Receiver Class
package com.mmm.rmsg;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class mstart extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Intent detcted.", Toast.LENGTH_LONG).show();
Intent pushIntent = new Intent(context, udp.class);
context.startService(pushIntent);
}
}
Service Class
package com.mmm.rmsg;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.PowerManager;
import android.widget.Toast;
import java.util.ArrayList;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
public class udp extends Service {
private static final String LOG_TAG =udp.class.getSimpleName();
GlobalState gs = (GlobalState)getApplication();
#Override
public IBinder onBind(Intent arg0){
return null;
}
#Override public int onStartCommand(Intent intent, int flags, int startId) {
setWakeLock();
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
new Thread(new Server()).start();
return START_STICKY;
}
private void setWakeLock(){
PowerManager.WakeLock mWakeLock;
PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
mWakeLock=powerManager.newWakeLock(PARTIAL_WAKE_LOCK, LOG_TAG);
}
public class Server implements Runnable {
#Override
public void run() {
ArrayList<String> list = new ArrayList<>();
ArrayList<String> clist = new ArrayList<>();
// here udp packets are recvd & processed into 2 list arrays
list.add(0, "MAIN FAIL");
list.add(1,"BOILER HEATER 20C");
list.add(2, "COOLING NEED ATT");
clist.add(0, "6");
clist.add(1,"1");
clist.add(2, "5");
GlobalState gs = (GlobalState)getApplication();
gs.setGmlist(list);
gs.setGclist(clist);
call();
}
}
public void call() {
Intent dialogIntent = new Intent(getBaseContext(), MsgView.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
}
}
Global Class
package com.mmm.rmsg;
import java.util.ArrayList;
import android.app.Application;
public class GlobalState extends Application
{
private ArrayList<String> Gmlist = new ArrayList<>();
private ArrayList<String> Gclist = new ArrayList<>();
private boolean chk = true;
private boolean cchk = true;
public ArrayList<String> getGmlist() {
chk = Gmlist.isEmpty();
if(chk==true)
{
Gmlist.add(0,"No Calls");
}
return Gmlist;
}
public ArrayList<String> getGclist() {
cchk = Gclist.isEmpty();
if(cchk==true)
{
Gclist.add(0,"0");
}
return Gclist;
}
public void setGmlist(ArrayList<String> Gmlit) {
for (int i = 0; i < Gmlit.size(); i++) {
this.Gmlist.add(i, Gmlit.get(i));
}
}
public void setGclist(ArrayList<String> Gclit) {
for (int i = 0; i < Gclit.size(); i++) {
this.Gmlist.add(i, Gclit.get(i));
}
}
}
Display Class
package com.mmm.rmsg;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.content.Context;
import android.graphics.Color;
import android.widget.ArrayAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Arrays;
public class MsgView extends AppCompatActivity {
ListView listView ;
ArrayList<String> mlist = new ArrayList<>();
ArrayList<String> plist = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_msg_view);
// Get ListView object from xml
listView = (ListView) findViewById(R.id.list);
GlobalState gs = (GlobalState) getApplication();
mlist= gs.getGmlist();
plist= gs.getGclist();
String[] msgArray = mlist.toArray(new String[mlist.size()]);
Arrays.toString(msgArray);
String[] clrArray = plist.toArray(new String[plist.size()]);
Arrays.toString(clrArray);
listView.setAdapter(new ColorArrayAdapter(this, android.R.layout.simple_list_item_1, msgArray,clrArray));
}
public class ColorArrayAdapter extends ArrayAdapter<Object>{
private String[] list;
private String[] p;
public ColorArrayAdapter(Context context, int textViewResourceId,
Object[] objects, Object[] obj) {
super(context, textViewResourceId, objects);
list = new String[objects.length];
for (int i = 0; i < list.length; i++)
list[i] = (String) objects[i];
p = new String[objects.length];
for (int i = 0; i < p.length; i++)
p[i] = (String) obj[i];
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = (TextView)super.getView(position, convertView, parent);
String c;
for(int x=0; x< list.length; x++)
{
c=chk(x,p);
if("R".equals(c) && position==x ) {
view.setBackgroundColor(Color.RED);
}
else
if("Y".equals(c) && position==x) {
view.setBackgroundColor(Color.YELLOW);
}
else
if("G".equals(c) && position==x) {
view.setBackgroundColor(Color.GREEN);
}
}
return view;
}
}
public String chk(int idx, String[] table){
String res;
if("6".equals(table[idx]) || "7".equals(table[idx]) || "8".equals(table[idx])) {
res = "R";
}
else
if("4".equals(table[idx]) || "5".equals(table[idx])) {
res = "Y";
}
else
if("1".equals(table[idx])|| "2".equals(table[idx]) || "3".equals(table[idx]) ) {
res = "G";
}
else{
res = "W";
}
return res;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_msg_view, 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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy(){
super.onDestroy();
}
}
You haven't started your thread. You can do it like this:
Thread initBkgThread = new Thread(new Runnable() {
public void run() {
udp();
}
});
initBkgThread .start();
Is this a full code or just some snips?
First thing is that your text1 is not initialized.
text1 = findViewById(R.id.<id_of_text_view_in_activity_calls_layout>) ?
To start an activity from your service you should create your intent like:
//Starting Smsgs
Intent startAct = new Intent(context, Smsgs.class);
startAct.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startAct);
You need at least two thread for this, one for the receiving of the UDP packets and the other is to compute the data. You need to modify your udp() function like this:
//Warning, I did not test this code, handle it like pseude-code.
private void udp(){
// ...
// Wait to receive a datagram
dsocket.receive(packet);
Thread showMsg = new Thread(new Runnable() {
public void run() {
// Convert the contents to a string,
String message = new String(buffer, 0, packet.getLength());
Intent intent = new Intent(this, Smsgs.class);
intent.putExtra("msg",message);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
showMsg.start();
// ...
}
and also don't forget to start your another thread: initBkgThread.start()
hope it helps.
I am trying to develop a simple application for download using DownloadManager but I need to do some changes, I want to download using ProgressbarDialog so how to do.
class DownloadReceiver
if(downloader == null) return;
long completeId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
if(completeId == downloadTaskId){
Query query = new Query();
query.setFilterById(downloadTaskId);
Cursor cur = downloader.query(query);
if (cur.moveToFirst()) {
int columnIndex = cur.getColumnIndex(DownloadManager.COLUMN_STATUS);
if (DownloadManager.STATUS_SUCCESSFUL == cur.getInt(columnIndex)) {
//Download the task has been completed, remove
new VersionPersistent(context).clear();
String uriString = cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
File apkFile = new File(Uri.parse(uriString).getPath());
Intent installIntent = new Intent();
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
installIntent.setAction(Intent.ACTION_VIEW);
installIntent.setDataAndType(Uri.fromFile(apkFile),"application/vnd.android.package-archive");
context.startActivity(installIntent);
} else {
Toast.makeText(context, R.string.download_failure, Toast.LENGTH_SHORT).show();
}
}
cur.close();
and also
download and install
if ( latestVersion == null || !isNetworkActive() ) return;
downloader = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
Query query = new Query();
query.setFilterById(downloadTaskId);
Cursor cur = downloader.query(query);
// Download tasks already exists
if(cur.moveToNext()) return;
DownloadManager.Request task = new DownloadManager.Request(Uri.parse(latestVersion.targetUrl));
String apkName = extractName(latestVersion.targetUrl);
String title = String.format("%s - v%s", apkName,latestVersion.name);
task.setTitle(title);
task.setDescription(latestVersion.feature);
task.setVisibleInDownloadsUi(true);
task.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
task.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkName);
downloadTaskId = downloader.enqueue(task);
Thanks :)
USE this class to show progress bar , this will give you an idea for downloading an image.
DownloadImageTask.java
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
/** Reference to the view which should receive the image */
private final WeakReference imageRef;
public DownloadImageTask(ImageView imageView) {
imageRef = new WeakReference(imageView);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(DownloadImageActivity.this, "Wait", "Downloading...");
}
#Override
protected Bitmap doInBackground(String... params) {
InputStream input = null;
try {
URL url = new URL(params[0]);
// We open the connection
URLConnection conection = url.openConnection();
conection.connect();
input = new BufferedInputStream(url.openStream(), 8192);
// we convert the inputStream into bitmap
bitmap = BitmapFactory.decodeStream(input);
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return bitmap;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(Bitmap bitmap) {
progressDialog.dismiss();
if (isCancelled()) {
bitmap = null;
}
if (imageRef != null) {
ImageView imageView = imageRef.get();
if (imageView != null && bitmap != null) {
imageView.setImageBitmap(bitmap);
} else
Toast.makeText(DownloadImageActivity.this, "Error while downloading the image!", Toast.LENGTH_LONG).show();
}
}
}
give permission in AndroidMenifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
you want using progressDialog, does that mean you don't need to download in the background ?
My solution is:
using AsyncTask
init the profressDialog before you call task.execute()
then show the dialog in onPreExecute
download file doInBackfround
update progess in onProgressUpdate
and dosomething you want when download complete in onPostExecute
you can learn AsyncTask and HttpURLConnection and IO Stream
You should use DownloadManager's
DownloadManager.query(DownloadManager.Query)
This gives you a Cursor to browse the columns COLUMN_TOTAL_SIZE_BYTES (Total size of the download in bytes) and COLUMN_BYTES_DOWNLOADED_SO_FAR (Number of bytes download so far).
With this information, you'll have the details to update the ProgressBarDialog.
Use Asynctask for this. Try this.
private class DownloadFileTask extends AsyncTask<String, Void, String> {
ProgressDialog pd;
#Override
protected String doInBackground(String... params) {
// Your File Download Code here
}
#Override
protected void onPostExecute(String result) {
pd.dismiss();
}
#Override
protected void onPreExecute() {
pd = new ProgressDialog(yourActivity.this);
pd.setMessage("Please Wait...");
pd.show();
}
#Override
protected void onProgressUpdate(Void... values) {}
}
}
This is my working sample code. I use SeekBar instead of ProgressBar. Hope this help
Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.downloadmanager" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Layout file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
<SeekBar
android:id="#+id/seekBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
<LinearLayout
style="?android:buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:orientation="horizontal">
<Button
android:id="#+id/buttonStartDownload"
style="?android:buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="startDownload"
android:text="Start" />
<Button
android:id="#+id/buttonCancelDownload"
style="?android:buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="cancelDownload"
android:text="Cancel" />
<Button
android:id="#+id/buttonViewDownloads"
style="?android:buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="viewDownloads"
android:text="View" />
</LinearLayout>
</RelativeLayout>
MainActivity.java:
package com.example.downloadmanager;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
public class MainActivity extends AppCompatActivity {
private DownloadManager mDownloadManager;
private long mDownloadReference;
private TextView mTextView;
private SeekBar mSeekBar;
private static Cursor mCursor;
private static boolean mDownloading = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.textView);
mSeekBar = (SeekBar) findViewById(R.id.seekBar);
// Set filter to only when download is complete and register broadcast receiver
IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(downloadReceiver, filter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
// noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void startDownload(View view) {
mDownloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
Uri Download_Uri = Uri.parse("http://192.168.0.100/files/test.txt");
DownloadManager.Request request = new DownloadManager.Request(Download_Uri);
// Restrict the types of networks over which this download may proceed.
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
// Set whether this download may proceed over a roaming connection.
request.setAllowedOverRoaming(false);
// Set the title of this download, to be displayed in notifications (if enabled).
request.setTitle("My Download");
// Set a description of this download, to be displayed in notifications (if enabled)
request.setDescription("Android Data download using DownloadManager...");
// Set the local destination for the downloaded file to a path within the application's external files directory
request.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, "test.txt");
// Enqueue a new download and same the referenceId
mDownloadReference = mDownloadManager.enqueue(request);
new Thread(new Runnable() {
#Override
public void run() {
mDownloading = true;
while (mDownloading) {
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(mDownloadReference);
mCursor = mDownloadManager.query(q);
if (mCursor != null && mCursor.getCount() > 0) {
mCursor.moveToFirst();
int bytes_downloaded = mCursor.getInt(mCursor
.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int bytes_total = mCursor.getInt(mCursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
if (mCursor.getInt(mCursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
mDownloading = false;
}
final double dl_progress = ((bytes_downloaded * 100) / bytes_total);
runOnUiThread(new Runnable() {
#Override
public void run() {
mSeekBar.setProgress((int) dl_progress);
}
});
}
if (mCursor != null) {
mCursor.close();
}
}
}
}).start();
}
public void cancelDownload(View view) {
mDownloading = false;
if (mDownloadManager != null) {
mDownloadManager.remove(mDownloadReference);
}
mSeekBar.setProgress(0);
}
public void viewDownloads(View view) {
Intent i = new Intent();
i.setAction(DownloadManager.ACTION_VIEW_DOWNLOADS);
startActivity(i);
}
private BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if (mDownloadReference == referenceId) {
Uri uri = mDownloadManager.getUriForDownloadedFile(mDownloadReference);
if (uri != null) {
String mimeType = mDownloadManager.getMimeTypeForDownloadedFile(mDownloadReference);
File file = new File(uri.getPath());
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("FileName", file.getName());
jsonObject.put("FilePath", file.getAbsolutePath());
jsonObject.put("FileSize", file.length());
jsonObject.put("MimeType", mimeType);
String msg = "Download completed! \n\n" + jsonObject.toString(5);
mTextView.setText(msg);
} catch (JSONException e) {
mTextView.setText(e.getMessage());
}
}
}
}
};
}
When I try to start my IntenetService I get no errors, but it never hits the breakpoint in onHandleIntent
MainActivity.java
package com.peterchappy.filewatcher.activities;
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.View;
import android.widget.Button;
import com.peterchappy.filewatcher.R;
import com.peterchappy.filewatcher.services.FileDownloadService;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class MainActivity extends Activity {
public static final String INTENT_EXTRA_FILE_URL = "URL";
private FileDownloadBroadcastReceiver broadcastReceiver;
private Button go;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
go = (Button) findViewById(R.id.go);
go.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
downloadFile("http://www.reddit.com/");
}
});
}
#Override
protected void onStart() {
super.onStart();
broadcastReceiver = new FileDownloadBroadcastReceiver();
registerReceiver(broadcastReceiver, new IntentFilter(FileDownloadService.FILE_DOWNLOADED));
}
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(broadcastReceiver);
}
private void downloadFile(String text) {
Intent intent = new Intent(this, FileDownloadService.class);
intent.putExtra(INTENT_EXTRA_FILE_URL, text);
this.startService(intent);
}
private void readFileAndDisplayContent(String fileName) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(openFileInput(fileName)));
StringBuilder content = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
content.append(line).append("\n");
}
reader.close();
System.out.println(content.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
private class FileDownloadBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String localFileName = intent.getStringExtra(FileDownloadService.INTENT_LOCAL_FILE_NAME);
readFileAndDisplayContent(localFileName);
}
}
}
FileDownloadService.java
package com.peterchappy.filewatcher.services;
import android.app.IntentService;
import android.content.Intent;
import com.peterchappy.filewatcher.activities.MainActivity;
import com.peterchappy.filewatcher.helpers.FileDownloader;
public class FileDownloadService extends IntentService {
public static final String INTENT_LOCAL_FILE_NAME = "local_file_name";
public static final String FILE_DOWNLOADED = "FILE_DOWNLOADED";
public FileDownloadService() {
super("FILE_DOWNLOAD_SERVICE");
}
#Override
protected void onHandleIntent(Intent intent) {
FileDownloader fileDownloader = new FileDownloader(this);
String localFileName = fileDownloader.downloadFile(intent.getStringExtra(MainActivity.INTENT_EXTRA_FILE_URL));
Intent resultIntent = new Intent(FILE_DOWNLOADED);
resultIntent.putExtra(INTENT_LOCAL_FILE_NAME, localFileName);
sendBroadcast(resultIntent);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".activities.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<service android:name=".filewatcher.services.FileDownloadService"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Ok, now I think I see it in your manifest. <service> tag is outside <application> tag, try moving it inside.