I am trying to update a progress bar while downloading a file, but in my Service task I do not have any access to the UI. This means I cannot find the ProgressBar element using findViewByID in order to update the ProgressBar. Here is the relevant code:
MainActivity:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void startService(View view) {
startService(new Intent(getBaseContext(), MyService.class));
}
public void stopService(View view) {
stopService(new Intent(getBaseContext(), MyService.class));
}
}
MyService Class:
package com.example.services;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.net.MalformedURLException;
import java.net.URL;
import android.os.AsyncTask;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
public class MyService extends Service {
int counter = 0;
static final int UPDATE_INTERVAL = 1000;
private Timer timer = new Timer();
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
doSomethingRepeatedly();
try {
new DoBackgroundTask().execute(
new URL("http://www.amazon.com/somefiles.pdf"),
new URL("http://www.wrox.com/somefiles.pdf"),
new URL("http://www.google.com/somefiles.pdf"),
new URL("http://www.learn2develop.net/somefiles.pdf"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
if (timer != null){
timer.cancel();
}
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
private void doSomethingRepeatedly() {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Log.d("MyService", String.valueOf(++counter));
}
}, 0, UPDATE_INTERVAL);
}
private class DoBackgroundTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalBytesDownloaded = 0;
for (int i = 0; i < count; i++) {
totalBytesDownloaded += DownloadFile(urls[i]);
publishProgress((int) (((i + 1) / (float) count) * 100));
}
return totalBytesDownloaded;
}
protected void onProgressUpdate(Integer... progress) {
Log.d("Downloading files", String.valueOf(progress[0]) + "% downloaded");
Toast.makeText(getBaseContext(),
String.valueOf(progress[0]) + "% downloaded-"+counter,
Toast.LENGTH_LONG).show();
}
protected void onPostExecute(Long result) {
Toast.makeText(getBaseContext(), "Downloaded " + result + " bytes",
Toast.LENGTH_LONG).show();
//stopSelf();
}
}
private int DownloadFile(URL url) {
try {
//---simulate taking some time to download a file---
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//---return an arbitrary number representing
// the size of the file downloaded---
return 100;
}
}
Basically, I want to update the ProgressBar in my MainActivity by using the bytesDownloaded variable in my MyService class, but I'm not sure how to handle the Async call in my MainActivity. If that is even possible.
Thanks!
Related
This is such a basic issue that I am not sure what I could possibly be doing wrong. Sinch is not starting for me and I don't know why. I don't have enough experience with Sinch to diagnose why a basic command is not doing what it is supposed to do. Here's what I have:
I am trying to start and making the call from the Calling.java class. The code is as follows:
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.sinch.android.rtc.calling.Call;
import com.squareup.picasso.Picasso;
import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
public class Calling extends CallActivity {
private String calleeID;
private TextView serviceName;
Bundle callDetails;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calling);
callDetails = getIntent().getBundleExtra("callDetails");
//Setup end button
Button endCallButton = findViewById(R.id.endcall);
endCallButton.setOnClickListener(v -> endCall());
}
private void endCall() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
finishActivity(FLAG_ACTIVITY_PREVIOUS_IS_TOP);
finish();
}
// invoked when the connection with SinchServer is established
#Override
protected void onServiceConnected() {
//Setup Calling Screen
ImageView avatar = findViewById(R.id.dialingAvatar);
Picasso.get().load(callDetails.getString("Logo")).into(avatar);
TextView midScreenName = findViewById(R.id.memberName);
midScreenName.setText(callDetails.getString("Name"));
serviceName = findViewById(R.id.serviceName);
serviceName.setText(callDetails.getString("Service"));
TextView ratings = findViewById(R.id.rating);
ratings.setText(callDetails.getString("Rating") + " ★");
//Get CallerID and CalleeID
calleeID = callDetails.getString("CalleeID");
//Start sinch Service
if(!getSinchServiceInterface().isStarted()){
getSinchServiceInterface().startClient(callDetails.getString("CallerID"));
Call call = getSinchServiceInterface().callUserVideo(calleeID);
Intent callServiceScreen = new Intent(this, ServiceCallActivity.class);
callDetails.putString(SinchService.CALL_ID, call.getCallId());
callServiceScreen.putExtra("Call Details", callDetails);
startActivity(callServiceScreen);
}
}
#Override
public void onDestroy() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
super.onDestroy();
}
}
I am coming to Calling.java from Precall.java the code for that is:
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.sinch.android.rtc.SinchError;
import com.squareup.picasso.Picasso;
import org.json.JSONObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class precall extends CallActivity implements SinchService.StartFailedListener {
private Bundle memberDetails;
private String url;
private Button cancel;
private Button call;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_precall);
//url
url = apiCallPoints.userInfo;
//Set Member Text
memberDetails = getIntent().getBundleExtra("Member");
//Populate screen
ImageView avatar = findViewById(R.id.avatar);
Picasso.get().load(memberDetails.getString("Logo")).into(avatar);
TextView memberName = findViewById(R.id.membername);
memberName.setText(memberDetails.getString("Name"));
TextView rating = findViewById(R.id.rating);
rating.setText(memberDetails.getString("Rating") + " ★");
TextView serviceName = findViewById(R.id.servicename);
serviceName.setText(memberDetails.getString("Service"));
TextView overview = findViewById(R.id.overview);
overview.setText(memberDetails.getString("Overview"));
//Add button clicks
cancel = findViewById(R.id.cancel_button);
cancel.setOnClickListener(view -> finish());
cancel.setEnabled(false);
call = findViewById(R.id.yes_button);
call.setOnClickListener(view -> {
goToCalling();
});
call.setEnabled(false);
setHomeBar();
}
//this method is invoked when the connection is established with the SinchService
#Override
protected void onServiceConnected() {
call.setEnabled(true);
cancel.setEnabled(true);
getSinchServiceInterface().setStartListener(this);
}
#Override
protected void onPause() {
super.onPause();
}
#Override
public void onStartFailed(SinchError error) {
}
//Invoked when just after the service is connected with Sinch
#Override
public void onStarted() {
}
private void goToCalling() {
//Async search
CallBackendSync callBackendSync = new CallBackendSync();
Object [] params = {url, memberDetails};
callBackendSync.execute(params);
}
private void setHomeBar() {
final Button home = findViewById(R.id.home_button);
home.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(precall.this, SecondActivity.class));
}
});
final Button favourites = findViewById(R.id.star_button);
favourites.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(precall.this, Favourite_Page.class));
}
});
final Button profile_page = findViewById(R.id.person_button);
profile_page.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(getApplicationContext(), Profile.class));
}
});
final Button notifications = findViewById(R.id.notification_button);
notifications.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(precall.this, Notification_Page.class));
}
});
final Button service = findViewById(R.id.service_button);
service.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(precall.this, services.class));
}
});
}
class CallBackendSync extends AsyncTask {
OkHttpClient client = new OkHttpClient();
#Override
protected Object doInBackground(Object [] objects) {
String url = (String) objects[0];
Bundle memberDetails = (Bundle) objects[1];
//Get access token from shared preference
isLoggedIn loggedIn = new isLoggedIn(getApplicationContext());
String token = loggedIn.getToken();
if(token != null){
//Create request
Request request = new Request.Builder()
.url(url)
.addHeader("Authorization", "Bearer " + token)
.addHeader("Accept", "application/json")
.build();
try {
Response response = client.newCall(request).execute();
JSONObject results = new JSONObject(response.body().string());
String UserID = results.getString("UserId");
memberDetails.putString("CallerID", UserID);
Intent callIntent = new Intent(precall.this, Calling.class);
callIntent.putExtra("callDetails", memberDetails);
startActivity(callIntent);
return results;
}catch (Exception e){
e.printStackTrace();
}
} else {
startActivity(new Intent(precall.this, Login_page.class));
}
return null;
}
protected void onPostExecute(String s){
super.onPostExecute(s);
}
}
}
The failure is happening in SinchService.java
import com.sinch.android.rtc.AudioController;
import com.sinch.android.rtc.ClientRegistration;
import com.sinch.android.rtc.Sinch;
import com.sinch.android.rtc.SinchClient;
import com.sinch.android.rtc.SinchClientListener;
import com.sinch.android.rtc.SinchError;
import com.sinch.android.rtc.video.VideoController;
import com.sinch.android.rtc.calling.Call;
import com.sinch.android.rtc.calling.CallClient;
import com.sinch.android.rtc.calling.CallClientListener;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class SinchService extends Service {
private static final String APP_KEY = "is correct";
private static final String APP_SECRET = "is correct";
//private static final String ENVIRONMENT = "clientapi.sinch.com";
private static final String ENVIRONMENT = "sandbox.sinch.com";
public static final String CALL_ID = "CALL_ID";
static final String TAG = SinchService.class.getSimpleName();
private SinchServiceInterface mSinchServiceInterface = new SinchServiceInterface();
private SinchClient mSinchClient = null;
private String mUserId = "";
private StartFailedListener mListener;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
if(mSinchClient != null){
mSinchClient.terminate();
}
super.onDestroy();
}
private void start(String userName) {
mUserId = userName;
mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext())
.applicationKey(APP_KEY)
.applicationSecret(APP_SECRET)
.environmentHost(ENVIRONMENT)
.userId(userName)
.enableVideoCalls(true)
.build();
mSinchClient.setSupportCalling(true);
mSinchClient.startListeningOnActiveConnection();
mSinchClient.addSinchClientListener(new MySinchClientListener());
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
mSinchClient.checkManifest();
mSinchClient.start();
System.out.println("Is started: " + mSinchClient.isStarted());
}
private void stop() {
if(mSinchClient != null){
mSinchClient.terminate();
}
}
private boolean isStarted() {
if(mSinchClient != null){
return mSinchClient.isStarted();
} else {
return false;
}
}
#Override
public IBinder onBind(Intent intent) {
return mSinchServiceInterface;
}
public class SinchServiceInterface extends Binder {
public Call callUserVideo(String userId) {
return mSinchClient.getCallClient().callUserVideo(userId);
}
public String getUserName() {
return mUserId;
}
public boolean isStarted() {
return SinchService.this.isStarted();
}
public void startClient(String userName) {
start(userName);
}
public void stopClient() {
stop();
}
public void setStartListener(StartFailedListener listener) {
mListener = listener;
}
public Call getCall(String callId) {
return mSinchClient.getCallClient().getCall(callId);
}
public VideoController getVideoController() {
return mSinchClient.getVideoController();
}
public AudioController getAudioController() {
return mSinchClient.getAudioController();
}
}
public interface StartFailedListener {
void onStartFailed(SinchError error);
void onStarted();
}
private class MySinchClientListener implements SinchClientListener {
#Override
public void onClientFailed(SinchClient client, SinchError error) {
if (mListener != null) {
mListener.onStartFailed(error);
}
mSinchClient.terminate();
mSinchClient = null;
}
#Override
public void onClientStarted(SinchClient client) {
Log.d(TAG, "SinchClient started");
if (mListener != null) {
mListener.onStarted();
}
}
#Override
public void onClientStopped(SinchClient client) {
Log.d(TAG, "SinchClient stopped");
}
#Override
public void onLogMessage(int level, String area, String message) {
switch (level) {
case Log.DEBUG:
Log.d(area, message);
break;
case Log.ERROR:
Log.e(area, message);
break;
case Log.INFO:
Log.i(area, message);
break;
case Log.VERBOSE:
Log.v(area, message);
break;
case Log.WARN:
Log.w(area, message);
break;
}
}
#Override
public void onRegistrationCredentialsRequired(SinchClient client,
ClientRegistration clientRegistration) {
}
}
private class SinchCallClientListener implements CallClientListener {
#Override
public void onIncomingCall(CallClient callClient, Call call) {
Log.d(TAG, "Incoming call");
Intent intent = new Intent(SinchService.this, Calling.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchService.this.startActivity(intent);
}
}
}
And the base activity is CallActivity.java
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.sinch.android.rtc.calling.Call;
import com.squareup.picasso.Picasso;
import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
public class Calling extends CallActivity {
private String calleeID;
private TextView serviceName;
Bundle callDetails;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calling);
callDetails = getIntent().getBundleExtra("callDetails");
//Setup end button
Button endCallButton = findViewById(R.id.endcall);
endCallButton.setOnClickListener(v -> endCall());
}
private void endCall() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
finishActivity(FLAG_ACTIVITY_PREVIOUS_IS_TOP);
finish();
}
// invoked when the connection with SinchServer is established
#Override
protected void onServiceConnected() {
//Setup Calling Screen
ImageView avatar = findViewById(R.id.dialingAvatar);
Picasso.get().load(callDetails.getString("Logo")).into(avatar);
TextView midScreenName = findViewById(R.id.memberName);
midScreenName.setText(callDetails.getString("Name"));
serviceName = findViewById(R.id.serviceName);
serviceName.setText(callDetails.getString("Service"));
TextView ratings = findViewById(R.id.rating);
ratings.setText(callDetails.getString("Rating") + " ★");
//Get CallerID and CalleeID
calleeID = callDetails.getString("CalleeID");
//Start sinch Service
if(!getSinchServiceInterface().isStarted()){
getSinchServiceInterface().startClient(callDetails.getString("CallerID"));
Call call = getSinchServiceInterface().callUserVideo(calleeID);
Intent callServiceScreen = new Intent(this, ServiceCallActivity.class);
callDetails.putString(SinchService.CALL_ID, call.getCallId());
callServiceScreen.putExtra("Call Details", callDetails);
startActivity(callServiceScreen);
}
}
#Override
public void onDestroy() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
super.onDestroy();
}
}
I have been banging my head against this but I cannot figure out what's wrong. I sure it's something stupid and obvious that I can't see because I am too close to the code. But any ideas you guys have would be very helpful!
It looks like you are not waiting for it to start before you try to make a call. We recommend to start the service when the app starts. If you dont do that you need to wait or the onStarted event in the service for fire
I am trying to update a ProgressBar from a Service task. I implemented a BroadcastReceiver so that I can interact with the UI thread. I update the ProgressBar in the main activity, and receive the data from the MyService activity. The MyService activity executes an Async task and updates the intent that should be sent back in the OnProgressUpdate method.
Here is my code:
MainActivity:
package com.example.services;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.ProgressBar;
import static android.content.Intent.ACTION_ATTACH_DATA;
public class MainActivity extends AppCompatActivity {
private MyBroadRequestReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter(ACTION_ATTACH_DATA);
receiver = new MyBroadRequestReceiver();
registerReceiver( receiver, filter);
}
public void startService(View view) {
startService(new Intent(getBaseContext(), MyService.class));
//pb.setProgress();
}
public void stopService(View view) {
stopService(new Intent(getBaseContext(), MyService.class));
}
public class MyBroadRequestReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar);
int progress = intent.getFlags();
pb.setProgress(progress);
}
}
}
MyService:
package com.example.services;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.net.MalformedURLException;
import java.net.URL;
import android.os.AsyncTask;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
public class MyService extends Service {
int counter = 0;
static final int UPDATE_INTERVAL = 1000;
private Timer timer = new Timer();
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
doSomethingRepeatedly();
try {
new DoBackgroundTask().execute(
new URL("http://www.amazon.com/somefiles.pdf"),
new URL("http://www.wrox.com/somefiles.pdf"),
new URL("http://www.google.com/somefiles.pdf"),
new URL("http://www.learn2develop.net/somefiles.pdf"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
if (timer != null){
timer.cancel();
}
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
private void doSomethingRepeatedly() {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Log.d("MyService", String.valueOf(++counter));
}
}, 0, UPDATE_INTERVAL);
}
private class DoBackgroundTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalBytesDownloaded = 0;
for (int i = 0; i < count; i++) {
totalBytesDownloaded += DownloadFile(urls[i]);
//Intent broadcastIntent = new Intent();
//broadcastIntent.setAction(Intent.ACTION_ATTACH_DATA);
//sendBroadcast(broadcastIntent);
publishProgress((int) (((i + 1) / (float) count) * 100));
}
return totalBytesDownloaded;
}
protected void onProgressUpdate(Integer... progress) {
Log.d("Downloading files", String.valueOf(progress[0]) + "% downloaded");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.example.services.MainActivity");
//broadcastIntent.putExtra("progress",progress);
broadcastIntent.setFlags(progress[0]);
sendBroadcast(broadcastIntent);
Toast.makeText(getBaseContext(),
String.valueOf(progress[0]) + "% downloaded-"+counter,
Toast.LENGTH_LONG).show();
}
protected void onPostExecute(Long result) {
Toast.makeText(getBaseContext(), "Downloaded " + result + " bytes",
Toast.LENGTH_LONG).show();
//stopSelf();
}
}
private int DownloadFile(URL url) {
try {
//---simulate taking some time to download a file---
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//---return an arbitrary number representing
// the size of the file downloaded---
return 100;
}
}
Please take a look at my onProgressUpdate and tell me if I am doing this correclty. My ProgressBar is not being updated at all.
Because you don't startService ononCreate() Method. Service will not run.
Firs of all this is not good solution to the problem your solving. Please go through Google Android docs Backgournd guide
I suggest you should switch to DownloadManager.
Your intent filter is defining to "ACTION_ATTACH_DATA"
IntentFilter filter = new IntentFilter(ACTION_ATTACH_DATA);
So, send your broadcast like this:
Intent i = new Intent(ACTION_ATTACH_DATA);
sendBroadcast(i);
Also, don't forget to unregister the broadcast at onDestroy
I am working on Exoplayer Media Player in Android to Live Stream from an RTMP Media Source URL. I am new to this kind a development so I am following the official Tutorial. The live stream is working fine on all Android Devices! My Class for fetching the live stream is:
import android.annotation.SuppressLint;
import android.databinding.DataBindingUtil;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import com.example.juni1289.exoplayertest2.databinding.ActivityMainBinding;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.ext.rtmp.RtmpDataSourceFactory;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.util.Util;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private ExoPlayer player;
private boolean playWhenReady;
private static final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter();
private ComponentListener componentListener;
private final String TAG = "MainActivity";
private MediaSource videoSource;
private AdaptiveTrackSelection.Factory adaptiveTrackSelectionFactory;
private TrackSelector trackSelector;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
componentListener = new ComponentListener();
initializePlayer();
}
private void initializePlayer() {
if (player == null) {
// a factory to create an AdaptiveVideoTrackSelection
adaptiveTrackSelectionFactory = new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
trackSelector = new DefaultTrackSelector(adaptiveTrackSelectionFactory);
player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(this),
trackSelector,
new DefaultLoadControl());
binding.videoView.setPlayer(player);
RtmpDataSourceFactory rtmpDataSourceFactory = new RtmpDataSourceFactory();
// Produces Extractor instances for parsing the media data.
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
// This is the MediaSource representing the media to be played.
videoSource = new ExtractorMediaSource(Uri.parse(""),
rtmpDataSourceFactory, extractorsFactory, null, null);
playWhenReady = true;
player.prepare(videoSource);
player.setPlayWhenReady(playWhenReady);
player.addListener(componentListener);
}
}
private void releasePlayer() {
if (player != null) {
player.removeListener(componentListener);
playWhenReady = player.getPlayWhenReady();
player.release();
player = null;
}
}
#Override
public void onPause() {
super.onPause();
if (Util.SDK_INT <= 23) {
releasePlayer();
}
}
#Override
public void onStop() {
super.onStop();
if (Util.SDK_INT > 23) {
releasePlayer();
}
}
#Override
public void onResume() {
super.onResume();
hideSystemUi();
if ((Util.SDK_INT <= 23 || player == null)) {
initializePlayer();
}
}
#SuppressLint("InlinedApi")
private void hideSystemUi() {
binding.videoView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
private class ComponentListener extends Player.DefaultEventListener {
#Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
super.onTimelineChanged(timeline, manifest, reason);
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
super.onTracksChanged(trackGroups, trackSelections);
}
#Override
public void onLoadingChanged(boolean isLoading) {
super.onLoadingChanged(isLoading);
}
#Override
public void onRepeatModeChanged(int repeatMode) {
super.onRepeatModeChanged(repeatMode);
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
super.onShuffleModeEnabledChanged(shuffleModeEnabled);
}
#Override
public void onPlayerError(ExoPlaybackException error) {
super.onPlayerError(error);
}
#Override
public void onPositionDiscontinuity(int reason) {
super.onPositionDiscontinuity(reason);
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
super.onPlaybackParametersChanged(playbackParameters);
}
#Override
public void onSeekProcessed() {
super.onSeekProcessed();
}
#Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
super.onTimelineChanged(timeline, manifest);
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
String stateString;
switch (playbackState) {
case ExoPlayer.STATE_IDLE:
stateString = "ExoPlayer.STATE_IDLE -";
break;
case ExoPlayer.STATE_BUFFERING:
stateString = "ExoPlayer.STATE_BUFFERING -";
break;
case ExoPlayer.STATE_READY:
stateString = "ExoPlayer.STATE_READY -";
break;
case ExoPlayer.STATE_ENDED:
stateString = "ExoPlayer.STATE_ENDED -";
break;
default:
stateString = "UNKNOWN_STATE -";
break;
}
Log.e(TAG, "changed state to " + stateString
+ " playWhenReady: " + playWhenReady);
}
}
}
The Gradle Dependencies
implementation 'com.google.android.exoplayer:exoplayer-core:2.7.3'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.7.3'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.7.3'
implementation 'com.google.android.exoplayer:extension-rtmp:2.7.3'
The URL is from Nginx Server implemented in the background, the backend live streaming software used is Wirecast using MacBook.
The problem I am facing is that when I have lost the Wifi connection (working),the Live stream won't resume at all. Similarly is with the 3G/4G Mobile Network Connection that once it goes down the live stream won't resume back.
I have followed the given tutorial and searched many of the forums for the problem resolution! But I am unable to find any resource information in order to rectify the problem!
I purposed a solution for me that a Broadcast receiver is registered in the MainActivity that will check of Internet Connections, once it changes it state the Exoplayer will be re-initialized. But this has limitation, that it only works when the Wifi or the Mobile Data Connection will turn on or off!
I want Exoplayer to resume the live stream when Wifi or Mobile Data Connection goes down and then it got some life and the Exoplayer resume the live stream to be watch again!
Any help or guidance will be highly appreciated! As I am new to this development, any blunders can occur in my code.
I am also trying with the following code too:
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Surface;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.ext.rtmp.RtmpDataSourceFactory;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultAllocator;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
public class MainActivity extends AppCompatActivity implements VideoRendererEventListener {
private SimpleExoPlayerView exoPlayerView;
private final String logKEY = "MainActivity";
private SimpleExoPlayer player;
private MediaSource videoSource;
private final String url = "myurl";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initExoPlayer();
}
private void initExoPlayer() {
try {
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
AdaptiveTrackSelection.Factory videoSelectionFactory=new AdaptiveTrackSelection.Factory(bandwidthMeter);
//TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(videoSelectionFactory);
/////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//Create the player
DefaultAllocator defaultAllocator = new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE);
DefaultLoadControl defaultLoadControl = new DefaultLoadControl(defaultAllocator, 30,
30, 10, DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS,
DefaultLoadControl.DEFAULT_TARGET_BUFFER_BYTES, DefaultLoadControl.DEFAULT_PRIORITIZE_TIME_OVER_SIZE_THRESHOLDS);
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, defaultLoadControl);
exoPlayerView.setPlayer(player);
exoPlayerView.setUseController(false);
RtmpDataSourceFactory rtmpDataSourceFactory = new RtmpDataSourceFactory();
// Produces Extractor instances for parsing the media data.
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
// This is the MediaSource representing the media to be played.
videoSource = new ExtractorMediaSource(Uri.parse(url),
rtmpDataSourceFactory, extractorsFactory, null, null);
// Prepare the player with the source.
player.prepare(videoSource);
//auto start playing
player.setPlayWhenReady(true);
//adding listeners
player.addListener(new ExoPlayer.EventListener() {
#Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
if (isLoading) {
Log.e(logKEY, "loadingChanged:::true");
} else {
Log.e(logKEY, "loadingChanged:::false");
}
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
Log.e(logKEY, "Listener-onPlayerError...");
player.stop();
player.prepare(videoSource);
player.setPlayWhenReady(true);
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
});
} catch (Exception e) {
Log.e(logKEY, "error:::" + e.toString());
e.printStackTrace();
}
}
private void initView() {
exoPlayerView = findViewById(R.id.exoPlayerView);
}
#Override
public void onVideoEnabled(DecoderCounters counters) {
}
#Override
public void onVideoDecoderInitialized(String decoderName, long initializedTimestampMs, long initializationDurationMs) {
}
#Override
public void onVideoInputFormatChanged(Format format) {
}
#Override
public void onDroppedFrames(int count, long elapsedMs) {
}
#Override
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
Log.e(logKEY, "onVideoSizeChanged [" + " width: " + width + " height: " + height + "]");
Log.e(logKEY, "RES:(WxH):" + width + "X" + height + "\n " + height + "p");
}
#Override
public void onRenderedFirstFrame(Surface surface) {
}
#Override
public void onVideoDisabled(DecoderCounters counters) {
}
#Override
protected void onStop() {
super.onStop();
Log.e(logKEY, "onStop()...");
}
#Override
protected void onStart() {
super.onStart();
Log.e(logKEY, "onStart()...");
}
#Override
protected void onResume() {
super.onResume();
Log.e(logKEY, "onResume()...");
}
#Override
protected void onPause() {
super.onPause();
Log.e(logKEY, "onPause()...");
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.e(logKEY, "onDestroy()...");
player.release();
}
}
The above is also having the said issues!
This is my code for getting BeaconFence.It's take too much time and not provide accurate information i fetch two fence lost and found
//BeaconFenceActivity.java
import android.Manifest;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.azilen.awarenessapidemo.R;
import com.google.android.gms.awareness.Awareness;
import com.google.android.gms.awareness.fence.AwarenessFence;
import com.google.android.gms.awareness.fence.BeaconFence;
import com.google.android.gms.awareness.fence.FenceState;
import com.google.android.gms.awareness.fence.FenceUpdateRequest;
import com.google.android.gms.awareness.state.BeaconState;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.ResultCallbacks;
import com.google.android.gms.common.api.Status;
import java.util.Arrays;
import java.util.List;
public class BeaconFenceActivity extends AppCompatActivity {
private GoogleApiClient mGoogleApiClient;
private static final int PERMISSION_REQUEST_ACCESS_FINE_LOCATION = 940;
private TextView txtBeacon;
private static final String BEACON_FENCE_KEY = "BEACON_FENCE_KEY";
private static final int BEACON_ZONE_IN = 2;
private static final int BEACON_ZONE_OUT = 1;
private PendingIntent mPendingIntent;
private BeaconFenceReceiver mBeaconFenceReceiver;
private ProgressDialog mProgress;
//Replace this with app's Google project name
private static final List<BeaconState.TypeFilter> BEACON_TYPE_FILTERS = Arrays.asList
(BeaconState.TypeFilter.with("awarenessapidemo-158205", "beacondemo"));
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_beacon_fence);
mProgress = new ProgressDialog(BeaconFenceActivity.this);
mProgress.setTitle("Geting Near Beacon");
mProgress.setMessage("Please wait..");
txtBeacon = (TextView) findViewById(R.id.txt_fence_beacon);
mGoogleApiClient = new GoogleApiClient.Builder(BeaconFenceActivity.this).addApi(Awareness.API).build();
mGoogleApiClient.connect();
mBeaconFenceReceiver = new BeaconFenceReceiver();
Intent intent = new Intent(BeaconFenceReceiver.BEACON_FENCE_RECEIVER_ACTION);
mPendingIntent = PendingIntent.getBroadcast(BeaconFenceActivity.this, 1, intent, 0);
}
#Override
protected void onStart() {
super.onStart();
getBeaconDetails();
registerReceiver(mBeaconFenceReceiver, new IntentFilter(BeaconFenceReceiver.BEACON_FENCE_RECEIVER_ACTION));
}
#Override
protected void onStop() {
super.onStop();
unregisterFences();
unregisterReceiver(mBeaconFenceReceiver);
}
private void getBeaconDetails() {
mProgress.show();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_REQUEST_ACCESS_FINE_LOCATION);
mProgress.hide();
} else {
AwarenessFence beaconFoundFence = BeaconFence.found(BEACON_TYPE_FILTERS);
AwarenessFence lostFence = BeaconFence.lost(BEACON_TYPE_FILTERS);
AwarenessFence orFence = AwarenessFence.or(lostFence, beaconFoundFence);
Awareness.FenceApi.updateFences(mGoogleApiClient,
new FenceUpdateRequest.Builder()
.addFence(BEACON_FENCE_KEY, orFence, mPendingIntent)
/* .addFence(BEACON_FENCE_KEY, beaconFoundFence, mPendingIntent)
.addFence(BEACON_FENCE_KEY, lostFence, mPendingIntent)
*/
.build()).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
Toast.makeText(BeaconFenceActivity.this, "Fence Registered", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(BeaconFenceActivity.this, "Fence Not Registered", Toast.LENGTH_SHORT).show();
}
}
});
mProgress.hide();
}
}
private void unregisterFences() {
Awareness.FenceApi.updateFences(
mGoogleApiClient,
new FenceUpdateRequest.Builder()
.removeFence(BEACON_FENCE_KEY)
.build()).setResultCallback(new ResultCallbacks<Status>() {
#Override
public void onSuccess(#NonNull Status status) {
Toast.makeText(BeaconFenceActivity.this, "Fence Removed", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(#NonNull Status status) {
Toast.makeText(BeaconFenceActivity.this, "Fence Not Removed", Toast.LENGTH_SHORT).show();
}
});
}
public void checkRestart(View view) {
getBeaconDetails();
registerReceiver(mBeaconFenceReceiver, new IntentFilter(BeaconFenceReceiver.BEACON_FENCE_RECEIVER_ACTION));
}
public class BeaconFenceReceiver extends BroadcastReceiver {
public static final String BEACON_FENCE_RECEIVER_ACTION = "com.azilen.awarenessapidemo.activities.fence.BeaconFenceReceiver.BEACON_FENCE_RECEIVER_ACTION";
#Override
public void onReceive(Context context, Intent intent) {
Log.e("Recived", "Received a Beacon Fence Broadcast");
FenceState fenceState = FenceState.extract(intent);
Log.e("FenceState Status:-", String.valueOf(fenceState.getFenceKey()));
if (TextUtils.equals(fenceState.getFenceKey(), BEACON_FENCE_KEY)) {
Log.e("FenceState:-", String.valueOf(fenceState.getCurrentState()));
switch (fenceState.getCurrentState()) {
case FenceState.TRUE: {
setBeaconState(BEACON_ZONE_IN);
Toast.makeText(BeaconFenceActivity.this, "You've entered the beacon zone!", Toast.LENGTH_SHORT).show();
Log.e("Beacon", "In Range");
break;
}
case FenceState.FALSE: {
setBeaconState(BEACON_ZONE_OUT);
Log.e("Beacon", "Out of Range");
Toast.makeText(BeaconFenceActivity.this, "You've Out of beacon Range!", Toast.LENGTH_SHORT).show();
break;
}
case FenceState.UNKNOWN: {
setBeaconState(FenceState.UNKNOWN);
Log.e("Beacon", "UNKNOWN");
Toast.makeText(BeaconFenceActivity.this, "Oops, Beacon status is unknown!", Toast.LENGTH_SHORT).show();
break;
}
}
}
}
}
private void setBeaconState(int beaconState) {
if (beaconState == BEACON_ZONE_IN) {
txtBeacon.setText("You've entered the beacon zone!");
} else if (beaconState == BEACON_ZONE_OUT) {
txtBeacon.setText("You're not in the beacon zone..");
} else {
txtBeacon.setText("Oops, Beacon status is unknown!");
}
}
}
I Hope you can understand my question.
Thank you.
I can't tell you why it is taking to much time.
But in case of the accuracy you have to keep in mind,
that your position to the beacons is calculated from
the signal/signalstrength that beacons send and like every signal in
the microwave spectrum it gets reflected, blocked etc.
The environment in which you use your beacons could be
far from ideal to get the accuracy you want with the information
provided by the beacons.
ProgressDialog quits updating when orientation of screen changes. I have put into place a fix that salvages the asynctask and sets the activity of the asynctask to the new activity after it is destroyed and rebuilt. The percentage complete on the progressdialog stays at the percentage it was at before the orientation change.
What am I missing?
package net.daleroy.fungifieldguide.activities;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Toast;
import net.daleroy.fungifieldguide.R;
import net.daleroy.fungifieldguide.fungifieldguideapplication;
public class FungiFieldGuide extends Activity {
//static final int PROGRESS_DIALOG = 0;
//ProgressThread progressThread;
private final static String LOG_TAG = FungiFieldGuide.class.getSimpleName();
fungifieldguideapplication appState;
private DownloadFile mTask;
public boolean mShownDialog;
ProgressDialog progressDialog;
private final static int DIALOG_ID = 1;
#Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
if ( id == DIALOG_ID ) {
mShownDialog = true;
}
}
private void onTaskCompleted() {
Log.i(LOG_TAG, "Activity " + this + " has been notified the task is complete.");
//Check added because dismissDialog throws an exception if the current
//activity hasn't shown it. This Happens if task finishes early enough
//before an orientation change that the dialog is already gone when
//the previous activity bundles up the dialogs to reshow.
if ( mShownDialog ) {
dismissDialog(DIALOG_ID);
Toast.makeText(this, "Finished..", Toast.LENGTH_LONG).show();
}
}
#Override
protected Dialog onCreateDialog(int id) {
switch(id) {
case DIALOG_ID:
progressDialog = new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading Database (only first run)...");
return progressDialog;
default:
return super.onCreateDialog(id);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
appState = ((fungifieldguideapplication)this.getApplication());
Object retained = getLastNonConfigurationInstance();
if ( retained instanceof DownloadFile ) {
Log.i(LOG_TAG, "Reclaiming previous background task.");
mTask = (DownloadFile) retained;
mTask.setActivity(this);
//showDialog(DIALOG_ID);
}
else {
if(!appState.service.createDataBase())
{
Log.i(LOG_TAG, "Creating new background task.");
//showDialog(DIALOG_ID);
mTask = new DownloadFile(this);
mTask.execute("http://www.codemarshall.com/Home/Download");
}
}
//showDialog(PROGRESS_DIALOG);
View btn_Catalog = findViewById(R.id.btn_Catalog);
btn_Catalog.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Intent i = new Intent(getBaseContext(), Cat_Genus.class);//new Intent(this, Total.class);
startActivity(i);
}
});
View btn_Search = findViewById(R.id.btn_Search);
btn_Search.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Intent i = new Intent(getBaseContext(), Search.class);//new Intent(this, Total.class);
startActivity(i);
}
});
}
#Override
public Object onRetainNonConfigurationInstance() {
mTask.setActivity(null);
return mTask;
}
#Override
public void onDestroy()
{
super.onDestroy();
//progressDialog.dismiss();
//progressDialog = null;
appState.service.ClearSearchParameters();
}
private class DownloadFile extends AsyncTask<String, Integer, Boolean>{
private FungiFieldGuide activity;
private boolean completed;
private String Error = null;
private String Content;
private DownloadFile(FungiFieldGuide activity) {
this.activity = activity;
}
#Override
protected void onPreExecute()
{
showDialog(DIALOG_ID);
}
#Override
protected Boolean doInBackground(String... urlarg) {
int count;
try {
URL url = new URL(urlarg[0]);
URLConnection conexion = url.openConnection();
conexion.setDoInput(true);
conexion.setUseCaches(false);
// this will be useful so that you can show a tipical 0-100% progress bar
int lenghtOfFile = conexion.getContentLength();
// downlod the file
InputStream input = new BufferedInputStream(conexion.getInputStream());
OutputStream output = new FileOutputStream("/data/data/net.daleroy.fungifieldguide/databases/Mushrooms.db");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int)total*100/lenghtOfFile);
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
Log.i(LOG_TAG, e.getMessage());
}
return null;
}
#Override
public void onProgressUpdate(Integer... args){
progressDialog.setProgress(args[0]);
}
#Override
protected void onPostExecute(Boolean result)
{
completed = true;
notifyActivityTaskCompleted();
}
private void notifyActivityTaskCompleted() {
if ( null != activity ) {
activity.onTaskCompleted();
}
}
private void setActivity(FungiFieldGuide activity) {
this.activity = activity;
if ( completed ) {
notifyActivityTaskCompleted();
}
}
}
}
This is not a real solution but to prevent this I just disabled orientation changes during the life of the AsyncTask with adding first:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
and when the job is done:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
Hope this helps.