Camera in Android app - android-camera

I am creating an app which required to perform from API 15 to API 23 using camera so what should be the best way to implement camera as camera class is deprecated in API 21 and also android.hardware.camera2 not able to implement on lower version then API 21.

The below code is something I have taken out of one of my projects, it has had a lot of stuff ripped out for the purpose of putting it on here so you will have to edit it for your needs. It uses the original camera api which is back compatible for your api needs.
public class RecordGameKam extends Fragment
implements TextureView.SurfaceTextureListener, View.OnClickListener {
private final static String TAG = "CameraRecordTexture";
private Camera mCamera;
private TextureView mTextureView;
int numberOfCameras;
int defaultCameraId;
private boolean isRecording = false;
protected MediaRecorder mediaRecorder;
#SuppressWarnings("ConstantConditions")
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
View rootView = new RelativeLayout(getActivity());
mTextureView = new TextureView(getActivity());
mTextureView.setSurfaceTextureListener(this);
//View parameters-----------------------------------------------------------------------
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
rootView.setLayoutParams(params);
((ViewGroup) rootView).addView(mTextureView);
return rootView;
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
// Find the total number of cameras available
numberOfCameras = Camera.getNumberOfCameras();
// Find the ID of the default camera
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0; i < numberOfCameras; i++) {
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
defaultCameraId = i;
}
}
try {
if (mCamera != null) {
//final Camera.Size previewSize = onMeasure();
//Camera.Size recorderSize = previewSize;
final Camera.Parameters params = mCamera.getParameters();
params.setPreviewSize(720, 480);
mCamera.setParameters(params);
mCamera.setDisplayOrientation(90);
mCamera.setPreviewTexture(surface);
mCamera.startPreview();
startContinuousAutoFocus();
}
} catch (IOException ioe) {
// Something bad happened
mCamera.release();
mCamera = null;
}
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// Ignored, Camera does all the work for us
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
try {
if (getActivity().getActionBar() != null) {
getActivity().getActionBar().show();
}
} catch (Exception e) {
e.printStackTrace();
}
releaseMediaRecorder();
return true;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
// Invoked every time there's a new Camera preview frame
}
private boolean setMediaRecorder() throws IllegalStateException {
try {
//Create a new instance of MediaRecorder.
mediaRecorder = new MediaRecorder();
//Unlock and set camera to Media recorder
mCamera.unlock();
mediaRecorder.setCamera(mCamera);
//Configure audio/video input
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
CamcorderProfile profile = null;
if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P)) {
profile = CamcorderProfile.get(CamcorderProfile.QUALITY_480P);
}
if (profile != null) {
mediaRecorder.setProfile(profile);
}
//Change oritentation
mediaRecorder.setOrientationHint(90 - 180 + 360);
mediaRecorder.setOutputFile(getFilename());
} catch (Exception e) {
e.printStackTrace();
}
//Attempt to prepare the configuration and record video.
try {
button.setBackgroundResource(R.drawable.camera_pressed);
mediaRecorder.prepare();
} catch (Exception e) {
e.printStackTrace();
mediaRecorder.release();
return false;
}
return true;
}
boolean startContinuousAutoFocus() {
Camera.Parameters params = mCamera.getParameters();
List<String> focusModes = params.getSupportedFocusModes();
assert focusModes != null;
String CAF_PICTURE = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE,
CAF_VIDEO = Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO,
supportedMode = focusModes
.contains(CAF_PICTURE) ? CAF_PICTURE : focusModes
.contains(CAF_VIDEO) ? CAF_VIDEO : "";
if (!supportedMode.equals("")) {
params.setFocusMode(supportedMode);
mCamera.setParameters(params);
return true;
}
return false;
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
enter code here

Related

Passing values from android to flutter but not from main activity

i'm implementing a third party android sdk in flutter and i want a message to be passed from android to flutter when sdk starts
i have implemented the sdk using platform channel just need to work on the callback code. In the code there is a function called onChannelJoin i want to send message to flutter when this function is called
Main Activity
public class MainActivity extends FlutterActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
final String CHANNEL = "samples.flutter.io/screen_record";
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodChannel.MethodCallHandler() {
#Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
// TODO
if (call.method.equals("startScreenShare")) {
Intent intent = new Intent(MainActivity.this , HelloAgoraScreenSharingActivity.class);
startActivity(intent);
} else {
result.notImplemented();
}
}
});
}
}
ScreenSharingActivity
public class HelloAgoraScreenSharingActivity extends Activity {
private static final String LOG_TAG = "AgoraScreenSharing";
private static final int PERMISSION_REQ_ID_RECORD_AUDIO = 22;
private ScreenCapture mScreenCapture;
private GLRender mScreenGLRender;
private RtcEngine mRtcEngine;
private boolean mIsLandSpace = false;
private void initModules() {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
if (mScreenGLRender == null) {
mScreenGLRender = new GLRender();
}
if (mScreenCapture == null) {
mScreenCapture = new ScreenCapture(getApplicationContext(), mScreenGLRender, metrics.densityDpi);
}
mScreenCapture.mImgTexSrcConnector.connect(new SinkConnector<ImgTexFrame>() {
#Override
public void onFormatChanged(Object obj) {
Log.d(LOG_TAG, "onFormatChanged " + obj.toString());
}
#Override
public void onFrameAvailable(ImgTexFrame frame) {
Log.d(LOG_TAG, "onFrameAvailable " + frame.toString());
if (mRtcEngine == null) {
return;
}
AgoraVideoFrame vf = new AgoraVideoFrame();
vf.format = AgoraVideoFrame.FORMAT_TEXTURE_OES;
vf.timeStamp = frame.pts;
vf.stride = frame.mFormat.mWidth;
vf.height = frame.mFormat.mHeight;
vf.textureID = frame.mTextureId;
vf.syncMode = true;
vf.eglContext14 = mScreenGLRender.getEGLContext();
vf.transform = frame.mTexMatrix;
mRtcEngine.pushExternalVideoFrame(vf);
}
});
mScreenCapture.setOnScreenCaptureListener(new ScreenCapture.OnScreenCaptureListener() {
#Override
public void onStarted() {
Log.d(LOG_TAG, "Screen Record Started");
}
#Override
public void onError(int err) {
Log.d(LOG_TAG, "onError " + err);
switch (err) {
case ScreenCapture.SCREEN_ERROR_SYSTEM_UNSUPPORTED:
break;
case ScreenCapture.SCREEN_ERROR_PERMISSION_DENIED:
break;
}
}
});
WindowManager wm = (WindowManager) getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE);
int screenWidth = wm.getDefaultDisplay().getWidth();
int screenHeight = wm.getDefaultDisplay().getHeight();
if ((mIsLandSpace && screenWidth < screenHeight) ||
(!mIsLandSpace) && screenWidth > screenHeight) {
screenWidth = wm.getDefaultDisplay().getHeight();
screenHeight = wm.getDefaultDisplay().getWidth();
}
setOffscreenPreview(screenWidth, screenHeight);
if (mRtcEngine == null) {
try {
mRtcEngine = RtcEngine.create(getApplicationContext(), "Agora_id", new IRtcEngineEventHandler() {
#Override
public void onJoinChannelSuccess(String channel, int uid, int elapsed) {
Log.d(LOG_TAG, "onJoinChannelSuccess " + channel + " " + elapsed);
}
#Override
public void onWarning(int warn) {
Log.d(LOG_TAG, "onWarning " + warn);
}
#Override
public void onError(int err) {
Log.d(LOG_TAG, "onError " + err);
}
#Override
public void onAudioRouteChanged(int routing) {
Log.d(LOG_TAG, "onAudioRouteChanged " + routing);
}
});
} catch (Exception e) {
Log.e(LOG_TAG, Log.getStackTraceString(e));
throw new RuntimeException("NEED TO check rtc sdk init fatal error\n" + Log.getStackTraceString(e));
}
mRtcEngine.setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING);
mRtcEngine.enableVideo();
if (mRtcEngine.isTextureEncodeSupported()) {
mRtcEngine.setExternalVideoSource(true, true, true);
} else {
throw new RuntimeException("Can not work on device do not supporting texture" + mRtcEngine.isTextureEncodeSupported());
}
mRtcEngine.setVideoProfile(Constants.VIDEO_PROFILE_360P, true);
mRtcEngine.setClientRole(Constants.CLIENT_ROLE_BROADCASTER);
}
}
private void deInitModules() {
RtcEngine.destroy();
mRtcEngine = null;
if (mScreenCapture != null) {
mScreenCapture.release();
mScreenCapture = null;
}
if (mScreenGLRender != null) {
mScreenGLRender.quit();
mScreenGLRender = null;
}
}
/**
* Set offscreen preview.
*
* #param width offscreen width
* #param height offscreen height
* #throws IllegalArgumentException
*/
public void setOffscreenPreview(int width, int height) throws IllegalArgumentException {
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("Invalid offscreen resolution");
}
mScreenGLRender.init(width, height);
}
private void startCapture() {
mScreenCapture.start();
}
private void stopCapture() {
mScreenCapture.stop();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hello_agora_screen_sharing);
}
public void onLiveSharingScreenClicked(View view) {
Button button = (Button) view;
boolean selected = button.isSelected();
button.setSelected(!selected);
if (button.isSelected()) {
initModules();
startCapture();
String channel = "ss_test" + System.currentTimeMillis();
channel = "ss_test";
button.setText("stop");
mRtcEngine.muteAllRemoteAudioStreams(true);
mRtcEngine.muteAllRemoteVideoStreams(true);
mRtcEngine.joinChannel(null, channel, "", 0);
} else {
button.setText("start");
mRtcEngine.leaveChannel();
stopCapture();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
deInitModules();
}
}
Dart Code
const platform = const MethodChannel('samples.flutter.io/screen_record');
try {
final int result = await platform.invokeMethod('startScreenShare');
} on PlatformException catch (e) {}
setState(() {
});

runOnUiThread not working properly

I am trying to create textview in android which display the remaining time(seconds).
Have used runOnUiThread and Hadnler for this and everything seems working fine(sysout and debug shows that both threads are executed and value is updated properly).
However, on UI the textview value is not updated properly. It gets updated with last value when the thread completes.
I am writing the below code inside private method of the fragment.
final TextView timerText = (TextView) mainView.findViewById(R.id.timerText);
timerText.setText(R.string.maxAllowedSeconds);
handler.post(new Runnable() {
#Override
public void run() {
while(true)
{
System.out.println("Text:"+ ""+maxAllowedSeconds);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
maxAllowedSeconds--;
if(maxAllowedSeconds <= 0)
break;
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
System.out.println("Running on UI Thread : " + maxAllowedSeconds);
timerText.setText("" + maxAllowedSeconds);
}
});
}
}
});
Gone through many of the previous questions in this area but none seems to have concrete solutions for this problem.
Thanks in advance.
SOLUTOIN:
Finally I used AsynchTask which worked perfectly as expected.
private class RapidFireAsyncTimerTask extends AsyncTask<Integer, Integer, Void> {
private Context context;
private View rootView;
public RapidFireAsyncTimerTask(Context ctx, View rootView) {
this.context = ctx;
this.rootView = rootView;
}
#Override
protected Void doInBackground(Integer... params) {
int maxSec= params[0];
while (true) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(--maxSec);
if (maxSec <= 0)
break;
}
return null;
}
#Override
protected void onProgressUpdate(final Integer... values) {
((TextView) rootView.findViewById(R.id.timerText)).setText("" + values[0]);
}
#Override
protected void onPostExecute(Void aVoid) {
//next task
}
}
Instead of Handler, it worked with AsynchTask(No runOnUiThread needed).
public RapidFireAsyncTimerTask(Context ctx, View rootView) {
this.context = ctx;
this.rootView = rootView;
}
#Override
protected Void doInBackground(Integer... params) {
int maxSec= params[0];
while (true) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(--maxSec);
if (maxSec <= 0)
break;
}
return null;
}
#Override
protected void onProgressUpdate(final Integer... values) {
((TextView) rootView.findViewById(R.id.timerText)).setText("" + values[0]);
}
#Override
protected void onPostExecute(Void aVoid) {
//next task
}
}

Background Service displays a timeout exception after some time in Android 6

This is a service running in the background, no Activity, began operating normally, but After about four hours, there will be a ConnectTimeoutException.
Connect to xxx.xxx.xxx.xxx time out.
This problem occurs in Android 6, I did not find this issue Android 4. When this problem occurs, I have to restart this phone, after which it connects properly for some time. When this problem occurs, other network applications on the phone runs properly.
public class mService extends Service{
Intent intent;
private Handler objHandlerCheckNetwork = new Handler();
private boolean mReflectFlg = false;
private static final int NOTIFICATION_ID = 101;
private static final Class<?>[] mSetForegroundSignature = new Class[] { boolean.class };
private static final Class<?>[] mStartForegroundSignature = new Class[] { int.class , Notification.class };
private static final Class<?>[] mStopForegroundSignature = new Class[] { boolean.class };
private NotificationManager mNM;
private Method mSetForeground;
private Method mStartForeground;
private Method mStopForeground;
private Object[] mSetForegroundArgs = new Object[1];
private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1];
private Runnable mHttpTestRunnable = new Runnable() {
#Override
public void run() {
if (httpTest()){
Log.e(GlobalData.getClassMethodName(),"true");
}else{
Log.e(GlobalData.getClassMethodName(),"false");
}
}
};
private Runnable mTasksCheckNetwork = new Runnable()
{
public void run()
{
Thread httpTestThread = new Thread(mHttpTestRunnable);;
httpTestThread.start();
objHandlerCheckNetwork.postDelayed(mTasksCheckNetwork, 1000*30);
}
};
#SuppressLint("NewApi")
#Override
public void onCreate() {
super.onCreate();
mNM = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE );
try {
mStartForeground = mService.class.getMethod("startForeground" , mStartForegroundSignature);
mStopForeground = mService.class.getMethod("stopForeground" , mStopForegroundSignature);
} catch (NoSuchMethodException e) {
mStartForeground = mStopForeground = null;
}
try {
mSetForeground = getClass().getMethod( "setForeground", mSetForegroundSignature);
} catch (NoSuchMethodException e) {
throw new IllegalStateException( "OS doesn't have Service.startForeground OR Service.setForeground!");
}
Intent intent = new Intent(this,UploadTableDataService.class );
intent.putExtra( "ficationId", NOTIFICATION_ID);
Notification.Builder builder = new Notification.Builder(this);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
builder.setContentIntent(contentIntent);
builder.setSmallIcon(R.drawable.gps);
builder.setContentTitle( "test" );
builder.setContentText( "test111" );
Notification notification = builder.getNotification();
startForegroundCompat( NOTIFICATION_ID, notification);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
//startService( new Intent( this, WifiService. class));
//startService( new Intent( this, VoiceService. class));
this.intent = intent;
Log.e(GlobalData.getClassMethodName(),"mService start!");
objHandlerCheckNetwork.postDelayed(mTasksCheckNetwork, 1000);
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
try{
objHandlerCheckNetwork.removeCallbacks(mTasksCheckNetwork);
}catch (Exception e) {
Log.d("DEBUG->", "onDestroy error - removeUpdates: ");
}
//stopForegroundCompat( NOTIFICATION_ID);
}
void invokeMethod(Method method, Object[] args) {
try {
method.invoke( this, args);
} catch (InvocationTargetException e) {
// Should not happen.
Log. w("ApiDemos" , "Unable to invoke method" , e);
} catch (IllegalAccessException e) {
// Should not happen.
Log. w("ApiDemos" , "Unable to invoke method" , e);
}
}
/**
* This is a wrapper around the new startForeground method, using the older
* APIs if it is not available.
*/
void startForegroundCompat( int id, Notification notification) {
if ( mReflectFlg) {
// If we have the new startForeground API, then use it.
if ( mStartForeground != null) {
mStartForegroundArgs[0] = Integer. valueOf(id);
mStartForegroundArgs[1] = notification;
invokeMethod( mStartForeground, mStartForegroundArgs);
return;
}
// Fall back on the old API.
mSetForegroundArgs[0] = Boolean. TRUE;
invokeMethod( mSetForeground, mSetForegroundArgs);
mNM.notify(id, notification);
} else {
if (Build.VERSION. SDK_INT >= 5) {
startForeground(id, notification);
} else {
// Fall back on the old API.
mSetForegroundArgs[0] = Boolean. TRUE;
invokeMethod( mSetForeground, mSetForegroundArgs);
mNM.notify(id, notification);
}
}
}
/**
* This is a wrapper around the new stopForeground method, using the older
* APIs if it is not available.
*/
void stopForegroundCompat( int id) {
if ( mReflectFlg) {
// If we have the new stopForeground API, then use it.
if ( mStopForeground != null) {
mStopForegroundArgs[0] = Boolean. TRUE;
invokeMethod( mStopForeground, mStopForegroundArgs);
return;
}
mNM.cancel(id);
mSetForegroundArgs[0] = Boolean. FALSE;
invokeMethod( mSetForeground, mSetForegroundArgs);
} else {
if (Build.VERSION. SDK_INT >= 5) {
stopForeground( true);
} else {
// Fall back on the old API. Note to cancel BEFORE changing the
// foreground state, since we could be killed at that point.
mNM.cancel(id);
mSetForegroundArgs[0] = Boolean. FALSE;
invokeMethod( mSetForeground, mSetForegroundArgs);
}
}
}
public static Boolean httpTest() {
HttpClient client= new DefaultHttpClient();;
try {
StringBuilder sb = new StringBuilder();
HttpParams httpParams = client.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 1000*5);
HttpConnectionParams.setSoTimeout(httpParams, 1000*10);
HttpResponse response = client.execute(new HttpGet("http://www.itnanny.com/default.htm"));
HttpEntity entity = response.getEntity();
if (entity != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"), 8192);
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
reader.close();
}
Log.e(GlobalData.getClassMethodName(),"result:"+sb.toString());
if (sb.toString().indexOf("ok") > -1){
return true;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
client.getConnectionManager().shutdown();;
}
return false;
}
}

Progress Dialog on Rajawali Vuforia example

It is possible to show progress dialog when loading the .obj model. I tried to call the ProgressDialog in RajawaliVuforiaExampleRenderer.java but it said "Can't create handler inside thread that has not called Looper.prepare()"
I have pasted part of the code here:
protected void initScene() {
mLight = new DirectionalLight(.1f, 0, -1.0f);
mLight.setColor(1.0f, 0, 0);
mLight.setPower(1);
getCurrentScene().addLight(mLight);
LoaderOBJ objParser = new LoaderOBJ(mContext.getResources(),
mTextureManager, R.raw.wall_obj);
try {
// Load model
objParser.parse();
wall = objParser.getParsedObject();
addChild(wall);
} catch (Exception e) {
e.printStackTrace();
}
}
EDITED:
I have read the comment from Abhishek Agarwal and updated the code for Renderer part, now i having problem on calling the ProgressDialog when loading the model, here is my code for the UI thread.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// receive file path
String filePath = this.getIntent().getStringExtra("FullFilePath");
Log.i(filePath, "FullFilePath:" + filePath);
waitDialog = ProgressDialog.show(this, "", "Loading", true);
waitDialog.show();
new ModelLoader().execute();
}
#Override
protected void setupTracker() {
int result = initTracker(TRACKER_TYPE_MARKER);
if (result == 1) {
result = initTracker(TRACKER_TYPE_IMAGE);
if (result == 1) {
super.setupTracker();
} else {RajLog.e("Couldn't initialize image tracker.");
}
} else {
RajLog.e("Couldn't initialize marker tracker.");
}}
protected void initApplicationAR() {
super.initApplicationAR();
createImageMarker("marker.xml");
}
protected void initRajawali() {
super.initRajawali();
mRenderer = new ModelRenderer(this);
mRenderer.setSurfaceView(mSurfaceView);
super.setRenderer(mRenderer);
mUILayout = this;
mUILayout.setContentView(mLayout, new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
private class ModelLoader extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
startVuforia();
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
waitDialog.dismiss();
}
}
Progress Dialog can be shown on the UIThread. So show progress dialog on the main thread not under GLThread
You can use Handler to be on threadUI :
`private Handler mHandler = new Handler();
...
mHandler.post(new Runnable() {
#Override
public void run() {
view_progressBar.setProgress(val);
}
});`

Refresh ListView when Device receives GCM IntentService Message

My app is able to receive messages from GCM and saves the messages to the SQLlite database on the phone. The messages are viewable in a activity that has a listview.
In the code below, the onPause() function refreshes the listView. This is not a good implementation because it only works if the activity is not displayed at the time of the update. If the activity is displayed at the time of an update, the list is static and does not update.
Questions:
How to I update the listview when the activity is being displayed? Or is there a way to use a background service to update the adapter, so that whenever the activity is displayed, it always shows the newest data.
is this kind of functionality currently not possible with android and I'll need to implement something else like 'pull-to-refresh'?
refreshing listview in OnResume() crashes the application, and shows a null pointer exception.
Activity:
public class NotesView extends Activity implements OnItemClickListener {
ListView listView;
NoteAdapter objAdapter;
NotificationsDatabase db = new NotificationsDatabase(this);
List<Notes> listAlerts;
String note;
String time;
TextView noteView;
TextView timeView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.note);
listView = (ListView) findViewById(R.id.notelist);
listView.setOnItemClickListener(this);
noteView = (TextView) findViewById(R.id.noteDisplay);
timeView = (TextView) findViewById(R.id.notetimeStampDisplay);
new MyTask().execute();
}
// My AsyncTask start...
class MyTask extends AsyncTask<Void, Void, List<Notes>> {
ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(NotesView.this);
pDialog.setMessage("Loading...");
pDialog.setCancelable(false);
pDialog.show();
if (isCancelled()) {
this.cancel(true);
}
}
#Override
protected List<Notes> doInBackground(Void... params) {
db.open();
listAlerts = db.getData();
if (isCancelled()) {
this.cancel(true);
}
return null;
}
protected void onPostExecute(List<Notes> alerts) {
if (null != pDialog && pDialog.isShowing()) {
pDialog.dismiss();
}
db.close();
setAdapterToListview();
}
}// end myTask
public void setAdapterToListview() {
objAdapter = new NoteAdapter(NotesView.this, R.layout.row_notes, listAlerts);
objAdapter.sortByNoteDesc();
objAdapter.notifyDataSetChanged();
listView.setAdapter(objAdapter);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
Intent intent = new Intent(
NotesView.this.getApplicationContext(),
TabBarExample.class);
intent.putExtra("goToTab", "Alerts");
startActivity(intent);
return true;
}
return super.onKeyDown(keyCode, event);
}
public void onItemClick(AdapterView<?> parent, View viewDel, int position,
long id) {
for (int i = 0; i < 1; i++) {
Notes item = listAlerts.get(position);
int ids = item.getId();
note = item.getNote();
time = item.getTimeStamp();
}
System.out.println(note + " " + time);
//
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
setContentView(R.layout.note);
listView = (ListView) findViewById(R.id.notelist);
listView.setAdapter(null);
listView.setOnItemClickListener(this);
noteView = (TextView) findViewById(R.id.noteDisplay);
timeView = (TextView) findViewById(R.id.notetimeStampDisplay);
new MyTask().execute();
}
#Override
protected void onDestroy() {
}
}
Code snippets From GCMIntentService
#Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
//String message = getString(R.string.gcm_message);
System.out.println("onMessage: ");
Bundle extras = intent.getExtras();
String message = extras.getString("message");
String event_id_from_server = extras.getString("server_id");
// displayMessage(context, message);
generateNotification(context, message);
saveMsg(message);
System.out.println("server id is " + event_id_from_server);
if (event_id_from_server != null) {
updateLocalDatabase(event_id_from_server);
}
}
public void saveMsg(String msg) {
boolean worked = true;
try {
NotificationsDatabase entry = new NotificationsDatabase(GCMIntentService.this);
entry.open();
java.util.Date date = new java.util.Date();
Timestamp x = new Timestamp(date.getTime());
String timeStamp = x.toLocaleString();
entry.createEntry(msg, timeStamp);
entry.close();
//update adapter service
} catch (Exception e) {
worked = false;
String error = e.toString();
System.out.println(error);
} finally {
if (worked) {
}
}
}
I cleaned up your code a little bit. Basically all the view assignments should be done once in onCreate, while the loading of the data should be done in onResume(). See if this helps:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.note);
listView = (ListView) findViewById(R.id.notelist);
listView.setAdapter(null);
listView.setOnItemClickListener(this);
noteView = (TextView) findViewById(R.id.noteDisplay);
timeView = (TextView) findViewById(R.id.notetimeStampDisplay);
}
#Override
protected void onResume() {
super.onResume();
new MyTask().execute();
}
#Override
protected void onPause() {
super.onPause();
}