.setPreviewFpsRange(): Having problems updating frames per second in camera .setParameters() - android-camera

UPDATED 28 October 2015 to reflect current progress.
I have an application that allows the user to set camera parameters for Motion JPEG recording, create an MJPEG file, and then the user can modify those settings and create another file with the updated settings. I am having a problem updating the frames per second setting when the initial value is something other than 30 FPS. When the initial value is 30 FPS, I can update to a different FPS level and sucessfully record a video AT THAT LEVEL. However, I cannot update from a level that is not equal to 30FPS to another FPM level. I get a crash with LogCat showing a problem at
camera.setParameters(parameters);
Full LogCat of error is below,
10-26 20:27:36.414: E/AndroidRuntime(2275): FATAL EXCEPTION: main
10-26 20:27:36.414: E/AndroidRuntime(2275): java.lang.RuntimeException: setParameters failed
10-26 20:27:36.414: E/AndroidRuntime(2275): at android.hardware.Camera.native_setParameters(Native Method)
10-26 20:27:36.414: E/AndroidRuntime(2275): at android.hardware.Camera.setParameters(Camera.java:1333)
10-26 20:27:36.414: E/AndroidRuntime(2275): at net.blepsias.riverwatch.RiverWatch.setCamera(RiverWatch.java:191)
10-26 20:27:36.414: E/AndroidRuntime(2275): at net.blepsias.riverwatch.RiverWatch.onClick(RiverWatch.java:167)
10-26 20:27:36.414: E/AndroidRuntime(2275): at android.view.View.performClick(View.java:3514)
10-26 20:27:36.414: E/AndroidRuntime(2275): at android.view.View$PerformClick.run(View.java:14111)
10-26 20:27:36.414: E/AndroidRuntime(2275): at android.os.Handler.handleCallback(Handler.java:605)
10-26 20:27:36.414: E/AndroidRuntime(2275): at android.os.Handler.dispatchMessage(Handler.java:92)
10-26 20:27:36.414: E/AndroidRuntime(2275): at android.os.Looper.loop(Looper.java:137)
10-26 20:27:36.414: E/AndroidRuntime(2275): at android.app.ActivityThread.main(ActivityThread.java:4429)
10-26 20:27:36.414: E/AndroidRuntime(2275): at java.lang.reflect.Method.invokeNative(Native Method)
10-26 20:27:36.414: E/AndroidRuntime(2275): at java.lang.reflect.Method.invoke(Method.java:511)
10-26 20:27:36.414: E/AndroidRuntime(2275): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
10-26 20:27:36.414: E/AndroidRuntime(2275): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
10-26 20:27:36.414: E/AndroidRuntime(2275): at dalvik.system.NativeStart.main(Native Method)
Checking the LogCat cited line 5 and 6, these correspond to:
(191) camera.setParameters(parameters);
(167) setCamera(camera);
Below is the application. I'll also include the layout .xml file for reference, as well as a screenshot for grounding.
RiverWatch.java
public class RiverWatch extends Activity implements OnClickListener, SurfaceHolder.Callback, Camera.PreviewCallback {
public static final String LOGTAG = "VIDEOCAPTURE";
String szBoundaryStart = "\r\n\r\n--myboundary\r\nContent-Type: image/jpeg\r\nContent-Length: ";
String szBoundaryDeltaTime = "\r\nDelta-time: 110";
String szBoundaryEnd = "\r\n\r\n";
private SurfaceHolder holder;
private Camera camera;
private CamcorderProfile camcorderProfile;
Spinner spinnerCamcorderProfile;
public TextView tvFramesPerSecond, tvJpegQuality, tvSegmentDuration;
boolean bRecording = false;
boolean bPreviewRunning = false;
int intFramesPerSecond = 30000; //this is 30fps...mult by 1,000
int intJpegQuality=50; //must be above 20
int intSegmentDuration=10;
boolean ckbxRepeat=false;
byte[] previewCallbackBuffer;
File mjpegFile;
FileOutputStream fos;
BufferedOutputStream bos;
Button btnStartRecord, btnStopRecord, btnExit, btnChange;
Camera.Parameters parameters;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Date T = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String szFileName = "videocapture-"+sdf.format(T)+"-";
try {
mjpegFile = File.createTempFile(szFileName, ".mjpeg", Environment.getExternalStorageDirectory());
} catch (Exception e) {
finish();
}
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.main);
tvFramesPerSecond = (TextView) this.findViewById(R.id.textboxframespersecondxml);
int iFPS = intFramesPerSecond/1000;
String szFPS = Integer.toString(iFPS);
tvFramesPerSecond.setClickable(true);
tvFramesPerSecond.setText(szFPS);
tvFramesPerSecond.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
getSupportedPreviewFpsRange();
}
});
tvJpegQuality = (TextView) this.findViewById(R.id.textboxJpegQualityxml);
String szJpegQuality = Integer.toString(intJpegQuality);
tvJpegQuality.setText(szJpegQuality);
tvSegmentDuration = (TextView) this.findViewById(R.id.textboxSegmentDurationxml);
String szSegmentDuration = Integer.toString(intSegmentDuration);
tvSegmentDuration.setText(szSegmentDuration);
btnStartRecord = (Button) this.findViewById(R.id.StartRecordButton);
btnStartRecord.setOnClickListener(this);
btnStopRecord = (Button) this.findViewById(R.id.StopRecordButton);
btnStopRecord.setOnClickListener(this);
btnExit = (Button) this.findViewById(R.id.ExitButton);
btnExit.setOnClickListener(this);
btnChange = (Button) this.findViewById(R.id.ChangeButton);
btnChange.setOnClickListener(this);
camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_480P);
SurfaceView cameraView = (SurfaceView) findViewById(R.id.CameraView);
holder = cameraView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.StartRecordButton:
try {
fos = new FileOutputStream(mjpegFile);
bos = new BufferedOutputStream(fos);
bRecording = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Toast.makeText(this, "Recording started.", Toast.LENGTH_SHORT).show();
break;
case R.id.StopRecordButton:
try {
bos.flush();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(this, "Recording stopped.", Toast.LENGTH_SHORT).show();
break;
case R.id.ChangeButton:
//Frames Per Second- expressed x1000 in the function
String szFPS=tvFramesPerSecond.getText().toString();
int iFPS = Integer.parseInt(szFPS);
intFramesPerSecond = iFPS *1000;
//Jpeg quality- cant be <20 or >100, checks this and populates field with entered or corrected value.
String szJpegQuality=tvJpegQuality.getText().toString();
int intJpegQualityTemp = Integer.parseInt(szJpegQuality);
if (intJpegQualityTemp < 21){//...can't be less than 21
intJpegQuality = 21;
}else if(intJpegQualityTemp > 100){//can't be greater than 100
intJpegQuality = 100;
}else{ //quality is between 21 and 100...
intJpegQuality = intJpegQualityTemp;
}
szJpegQuality = Integer.toString(intJpegQuality);
tvJpegQuality.setText(szJpegQuality);
//Segment duration
String szSegmentDuration=tvSegmentDuration.getText().toString();
intSegmentDuration = Integer.parseInt(szSegmentDuration);
releaseCamera();
setCamera(camera);
camera.startPreview();
Toast.makeText(this, "Change button pressed.", Toast.LENGTH_SHORT).show();
break;
case R.id.ExitButton:
System.exit(0);
break;
}
}
public void releaseCamera(){
camera.stopPreview();
//camera.release(); //...cause crash
//camera = null;
}
public void setCamera(Camera camera){
Camera.Parameters parameters=camera.getParameters();
parameters.setPreviewFpsRange(intFramesPerSecond, intFramesPerSecond);//note: This is fps x 1000 (!)
parameters.setPreviewSize(camcorderProfile.videoFrameWidth, camcorderProfile.videoFrameHeight);
Log.v(LOGTAG,"FPS: " + parameters.getSupportedPreviewFpsRange());
camera.setParameters(parameters);
}
public void getSupportedPreviewFpsRange(){
/****************************************************************
* getSupportedPreviewFpsRange()- Returns specified frame rate
* (.getSupportedPreviewFpsRange()) to log file and also displays
* as toast message.
****************************************************************/
Camera.Parameters camParameter = camera.getParameters();
List<int[]> frame = camParameter.getSupportedPreviewFpsRange();
Iterator<int[]> supportedPreviewFpsIterator = frame.iterator();
while (supportedPreviewFpsIterator.hasNext()) {
int[] tmpRate = supportedPreviewFpsIterator.next();
StringBuffer sb = new StringBuffer();
sb.append("SupportedPreviewRate: ");
for (int i = tmpRate.length, j = 0; j < i; j++) {
sb.append(tmpRate[j] + ", ");
}
Log.d(LOGTAG, "FPS6: " + sb.toString());
Toast.makeText(this, "FPS = "+sb.toString(), Toast.LENGTH_SHORT).show();
}//*****************end getSupportedPreviewFpsRange()**********************
}
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
}
#SuppressLint("NewApi")
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (!bRecording) {
if (bPreviewRunning = true){
camera.stopPreview();
} try {
parameters = camera.getParameters();
parameters.setPreviewSize(camcorderProfile.videoFrameWidth, camcorderProfile.videoFrameHeight);
parameters.setPreviewFpsRange(intFramesPerSecond, intFramesPerSecond);//note: This is fps x 1000 (!)
//p.setPreviewFrameRate(intFramesPerSecond);
camera.setParameters(parameters);
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(this);
camera.setDisplayOrientation(90);
camera.startPreview();
bPreviewRunning = true;
}
catch (IOException e) {
e.printStackTrace();
}
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (bRecording) {
bRecording = false;
try {
bos.flush();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
bPreviewRunning = false;
camera.release();
finish();
}
public void onPreviewFrame(byte[] b, Camera c) {
if (bRecording) {
// Assuming ImageFormat.NV21
if (parameters.getPreviewFormat() == ImageFormat.NV21) {
try {
YuvImage im = new YuvImage(b, ImageFormat.NV21, parameters.getPreviewSize().width, parameters.getPreviewSize().height, null);
Rect r = new Rect(0,0,parameters.getPreviewSize().width,parameters.getPreviewSize().height);
ByteArrayOutputStream jpegByteArrayOutputStream = new ByteArrayOutputStream();
im.compressToJpeg(r, intJpegQuality, jpegByteArrayOutputStream);//note: qual = 20 or less doesn't work.
byte[] jpegByteArray = jpegByteArrayOutputStream.toByteArray();
byte[] boundaryBytes = (szBoundaryStart + jpegByteArray.length + szBoundaryDeltaTime + szBoundaryEnd).getBytes();
bos.write(boundaryBytes);
bos.write(jpegByteArray);
bos.flush();
//bos.close();
} catch (IOException e) {
e.printStackTrace();
}
} else {
Log.v(LOGTAG,"NOT THE RIGHT FORMAT");
}
}
}
#Override
public void onConfigurationChanged(Configuration conf){
super.onConfigurationChanged(conf);
}
}
Layout main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/StartRecordButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Recording" />
<Button
android:id="#+id/StopRecordButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stop Recording" />
<Button
android:id="#+id/ChangeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dip"
android:text="Reset settings" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right">
<TextView
style="#style/myStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Frames/second:" />
<EditText
android:id="#+id/textboxframespersecondxml"
android:editable="true"
style="#style/myStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:text="0"
android:layout_marginRight="10dip"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right">
<TextView
style="#style/myStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="JPEG image quality:" />
<EditText
android:id="#+id/textboxJpegQualityxml"
android:editable="true"
style="#style/myStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:text="0"
android:layout_marginRight="10dip"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
style="#style/myStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:text="Camcorder profile: " />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right">
<TextView
style="#style/myStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Segment duration (file length):" />
<EditText
android:id="#+id/textboxSegmentDurationxml"
android:editable="true"
style="#style/myStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:text="0"
android:layout_marginRight="10dip"/>
<TextView
style="#style/myStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" minutes" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="right" >
<CheckBox
android:id="#+id/repeat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Repeat" />
<Button
android:id="#+id/ExitButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Exit Application" />
</LinearLayout>
<SurfaceView
android:id="#+id/CameraView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
Screenshot: Showing fields, buttons, and surface config
Resolution: It appears that much of the above erratic behaviour may be related to the primary testing device which is a Panasonic Toughpad JT-B1. Running
.getSupportedPreviewFpsRange();
on this device returns a range of 8,000-30,000 fps. However, many values in this range result in crashes, and some values outside of this range appear to work fine. Testing a Samsung S4 Active resulted in none of these inconsistencies, with all of the values in the returned range (4,000 - 30,000) working fine, and no tested values outside of this range demonstrating any functionality as expected.

Camera API does not allow to set the preview FPS range to arbitrary values. You are supposed to query the camera parameters for the list of supported ranges, and any other combination is not guaranteed to work.
In principle, using unsupported values for Camera.setParameters() is undefined behavior. Different devices will fail or work differently when you try the same inputs.
Definitely, though, you should stop preview to change camera parameters, and restart the preview after that.
Other than that, you probably can use a workaround to hold on to supported parameters. To achieve 2 fps, and switch to 10 fps, you don't need to change camera settings. Your logic can filter out relevant frames in your onPreviewFrame() by timestamp.
Furthermore, your code is suboptimal when it comes to preview callbacks. First of all, you should open the camera on a separate handler thread, then the preview callbacks will not arrive on the UI thread (the newer versions of Android become even more jealous about apps hijacking the Main thread for CPU or network intensive tasks).
Second, consider using camera.setPreviewCallbackWithBuffer() to avoid unnecessary garbage collection. An extra advantage of this technique is that if you only prepare one preview buffer, you will only receive preview callbacks when you release it. So, you can simply use the code:
public void onPreviewFrame(byte[] data, Camera camera) {
long timestampBeforecompression = SystemClock.uptimeMillis();
compress(data);
long compressionMillis = SystemClock.uptimeMillis() - timestampBeforecompression;
SystemClock.sleep(1000000/intFramesPerSecond - compressionMillis);
camera.addCallbackBuffer(data);
}
Maybe, you can be more precise if you also compensate for the current camera frame rate, but this is probably not critical when speaking about 2 or 3 FPS.
Finally, there is another hint: many devices still support the deprecated setPreviewFrameRate(), and even declare the supported FPS values that may be of interest for you:
[1, 2, 3, 4, 5, 8, 10, 15, 20, 30]
on my no-name Snapdragon-801 tablet.

Related

Scoped Storage won't allow FileInputStream access to file in DOWNLOADS, is there a workaround?

I import data from a downloaded spreadsheet into a Room database. This is what I need to do :
String filePath = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.getAbsolutePath();
String fileName = context.getString(R.my_file_name);
File importFile = new File(filePath + File.separator, fileName);
try {
FileInputStream stream = new FileInputStream(importFile);
// do stuff
} catch (Exception e1) {e1.printStackTrace();}
So, this doesn't work anymore(?) I haven't been able to find a concise explanation (in JAVA) of how to accomplish this simple operation going forward without asking for the MANAGE_EXTERNAL_STORAGE permission (an unacceptable solution) Help from the gurus?
So, need to set up intent in manifest, and leave old permissions for legacy android
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28"/>
<application
android:requestLegacyExternalStorage="true"
>
<activity
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
in mainActivity, set up file picker, create method to launch the picker, and create method to process picker result.
Main Activity :
private ActivityResultLauncher<Intent> launchFilePicker;
public File importFile;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
filePath = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS).
getAbsolutePath();
launchFilePicker = registerForActivityResult(
new ActivityResultContract<Intent, Uri>() {
#NonNull
#Override
public Intent createIntent(#NonNull Context context, Intent input) {
return input;
}
#Override
public Uri parseResult(int resultCode, #Nullable Intent result) {
if (result == null || resultCode != Activity.RESULT_OK) {
return null;
}
return result.getData();
}
},
this::getFileFromUri);
...
public void launchFileFinder() {
Intent pickerIntent = new Intent(ACTION_OPEN_DOCUMENT);
pickerIntent.addCategory(Intent.CATEGORY_OPENABLE);
pickerIntent.setType(" your mime type ");
pickerIntent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS));
launchFilePicker.launch(pickerIntent);
}
...
public void getFileFromUri(Uri result) {
String fileName = context.getString(R.my_file_name);
File importFile = new File(filePath + File.separator, fileName);
InputStream stream = null;
try {
stream = AppMainActivity.this.getContentResolver().openInputStream(result);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (stream != null) {
try {
FileInputStream stream = new FileInputStream(importFile);
} catch (IOException | InvalidFormatException e) {
e.printStackTrace();
}
}
}
}

Android widget background color not updating

I want to change the widget background transparency dynamically. The user can define a custom value in percent in my SettingsActivity. After I call updateWidget() from my activity the widget does not update immediately. It is only working if I re-add the widget.
When I set a breaking I see that updateWidgetListView() is called.
widget_layout_black.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/widget_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:background="#drawable/primary_rounded_background_black"
android:layout_height="wrap_content">
<TextView
android:id="#+id/newTaskButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:layout_gravity="center_vertical"
android:textIsSelectable="false"
android:fontFamily="sans-serif-light"
android:layout_marginBottom="2dp"
android:paddingTop="5dp"
android:paddingRight="10dp"
android:paddingLeft="10dp"
android:text="#string/tasks"
android:background="#color/black"
android:gravity="center_vertical"
android:textColor="#color/white"
android:textAppearance="?android:attr/textAppearanceMedium"
android:drawableRight="#drawable/add" />
</LinearLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/widgetScheduledTasksListView"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
android:layout_marginBottom="16dp"
android:dividerHeight="0dp"
android:divider="#null"
android:layout_centerHorizontal="true" />
<TextView
android:id="#+id/empty_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/noScheduledTasks"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#000000"
android:visibility="gone" />
SettingsActivity.java
public void updateWidget() {
Intent intent = new Intent(this, WidgetProvider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
int[] ids = {R.xml.widgetinfo};
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
sendBroadcast(intent);
}
WidgetProvider.java
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int numberOfWidgets = appWidgetIds.length;
for (int i = 0; i < numberOfWidgets; ++i) {
RemoteViews remoteViews = updateWidgetListView(context,appWidgetIds[i]);
remoteViews.setOnClickPendingIntent(R.id.newTaskButton, getPendingSelfIntent(context, ACTION_NEW));
appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
private RemoteViews updateWidgetListView(Context context, int appWidgetId) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout_black);
Intent svcIntent = new Intent(context, WidgetService.class);
svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
remoteViews.setRemoteAdapter(appWidgetId, R.id.widgetScheduledTasksListView, svcIntent);
remoteViews.setEmptyView(R.id.widgetScheduledTasksListView, R.id.empty_view);
final Intent onClickIntent = new Intent(context, WidgetProvider.class);
onClickIntent.setAction(WidgetProvider.ACTION_OPEN);
onClickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
onClickIntent.setData(Uri.parse(onClickIntent.toUri(Intent.URI_INTENT_SCHEME)));
final PendingIntent onClickPendingIntent = PendingIntent.getBroadcast(context, 0, onClickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setPendingIntentTemplate(R.id.widgetScheduledTasksListView, onClickPendingIntent);
remoteViews.setInt(R.id.widget_layout, "setBackgroundColor", getBackgroundWithTransparencyColor(context)); // Set background color
return remoteViews;
}
public int getBackgroundWithTransparencyColor(Context context) {
int white = context.getResources().getColor(R.color.white);
int transparencyInPercent = preferences.getInt(context.getResources().getString(R.string.keyWidgetBackgroundTransparency), 25);
try {
double value = 255.0 / 100 * (100 - transparencyInPercent);
return ColorUtils.setAlphaComponent(white, (int) value);
} catch (Exception e) {
e.printStackTrace();
return white;
}
}

GetChildView gets not called

I have searched similar threads but they didn't help me and they were light different or they still are unanswered, so I'll describe my trouble.
I have an ExpandableListView with a custom ExpandableListAdapter and I can show my Groups but not my Children. GetChildView don't get called anyway.
I would thank you for your Help.
EDIT:
If I log this section
...
client = (ExpandableListView)row.findViewById(R.id.field_expandable_list);
client.setFocusable(false);
client_adapter = new ClientAdapter(context, titles, allFields);
client.setAdapter(client_adapter);
Log.i("TAG", "WmsMApActivity::doClient:: Adapter #children: "+client_adapter.getChildrenCount(0)+
" ExpListView #children: "+client.getChildCount());
...
, then I get that
I/TAG(692): WmsMApActivity::doClient::0 Adapter #children: 13 ExpListView #children: 0
So, my Adapter gets Data but the variable client (ExpandableListView) don't realize, it has data although I properly set it.
My code is the following
Main Code
// view = Item of my ListView. We come from a OnClickItem Method
private void doClient(View view) {
ArrayList<String> titles = new ArrayList<String>();
titles.add("fields");
ArrayList allFields = transformFarmsResult(parentItems);
final Context context = getApplicationContext();
RelativeLayout mainLayout = (RelativeLayout) view.findViewById(R.id.relLayoutDrawer);
// We check whether the first item (0th position) is expanded
View lin_layout_field_list = view.findViewById(R.id.lin_layout_field_list);
if ( lin_layout_field_list != null ) { // Hide Field_list Layout
((ViewGroup) view).removeView(lin_layout_field_list);
} else {
mainLayout = (RelativeLayout) view.findViewById(R.id.relLayoutDrawer);
// ----------- Inflating ExpandableListView "Fields"
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.field_list, null);
client = (ExpandableListView)row.findViewById(R.id.field_expandable_list);
// Adapter Population
client_adapter = new ClientAdapter(context, titles, allFields);
client.setAdapter(client_adapter);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
TextView title_tv = (TextView)view.findViewById(R.id.title);
params.addRule(RelativeLayout.ALIGN_LEFT, title_tv.getId() );
params.addRule(RelativeLayout.BELOW, title_tv.getId());
mainLayout.addView(row, params);
// Listview Group click listener
client.setOnGroupClickListener(new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
Toast.makeText(context, "Group Clicked " + groupPosition, Toast.LENGTH_SHORT).show();
return false;
}
});
// Listview Group expanded listener
client.setOnGroupExpandListener(new OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
Toast.makeText(context, "Group " + groupPosition + " Expanded", Toast.LENGTH_SHORT).show();
}
});
// Listview Group collasped listener
client.setOnGroupCollapseListener(new OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
Toast.makeText(context, "Group " + groupPosition + " Collapsed", Toast.LENGTH_SHORT).show();;
}
});
// Listview on child click listener
client.setOnChildClickListener(new OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
Toast.makeText(context, "Group " + groupPosition + " : Child " + childPosition, Toast.LENGTH_SHORT).show();
return false;
}
});
}
}
Adapter
public class ClientAdapter extends BaseExpandableListAdapter{
private Context context;
//private String header_title;
private ArrayList<String> headers;
private ArrayList fields;
private int groupPosition = 0;
private LayoutInflater inflater;
public ClientAdapter(Context context, ArrayList<String> headers, ArrayList fields) {
this.context = context;
this.headers = headers;
this.fields = fields;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Just to check, whether I get correct ArrayList "fields"
Log.i("TAG","ClientAdapter::Constructor:: fields.size: "+fields.size());
for (int i=0;i<fields.size();i++)
Log.i("TAG","ClientAdapter::Constructor:: field["+i+"]: "+fields.get(i).toString());
}
#Override
public int getGroupCount() {
// Just 1 Group
return headers.size();
}
#Override
public String getGroup(int groupPosition) {
return headers.get(groupPosition);
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = convertView;
GroupHolder holder=null;
String title_item = getGroup(groupPosition);
if ( view == null ) {
holder = new GroupHolder();
view = inflater.inflate(R.layout.group_client, null);
holder.title = (TextView) view.findViewById(R.id.client_group_title);
view.setTag(holder);
} else {
holder = (GroupHolder) view.getTag();
}
holder.title.setText(title_item);
return view;
}
// Children
#Override
public int getChildrenCount(int groupPosition) {
return fields.size();
}
#Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return fields.get(childPosition);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = convertView;
ChildHolder holder;
Log.i("TAG", "ClientAdapter::getChildView:: 0 - parent.id: "+parent.getId());
final HashMap<String,Object> field = (HashMap<String,Object>) getChild(groupPosition, childPosition);
if (view == null) {
holder = new ChildHolder();
view = inflater.inflate(R.layout.child_client, null);
holder.title = (TextView) view.findViewById(R.id.client_child_title);
holder.map_icon = (ImageView) view.findViewById(R.id.client_child_icon);
holder.contour = (CheckBox) view.findViewById(R.id.client_child_checkbox);
convertView.setTag(holder);
} else {
holder = (ChildHolder) view.getTag();
}
// Handling of Title
String temp =(String)field.get(Constants._FIELDNAME);
Log.i("TAG", "ClientAdapter::getChildView:: title: "+temp);
holder.title.setText((String)field.get(Constants._FIELDNAME));
// Handling of Contour - If it exists!
if ( field.containsKey(Constants._BOUNDARY)) {
holder.contour.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (((CheckBox)v).isChecked()) {
Toast.makeText(context, "Contour enabled", Toast.LENGTH_LONG).show();
// TODO : Fade-in Contour in Graphics
} else {
Toast.makeText(context, "Contour disabled", Toast.LENGTH_LONG).show();
// TODO : Fade-in Contour in Graphics
}
}
});
} else { // If there is no Contour, remains the checkbox but it's not clickable, so, it's grey!
holder.contour.setFocusable(false);
holder.contour.setClickable(false);
}
// Handling of Map Icon
Bitmap bitmap_icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.gmaps_icon_24);
holder.map_icon.setImageBitmap(bitmap_icon);
// Applying gray filter if not referentiable
if ( !field.containsKey(Constants._LATITUDE) || !field.containsKey(Constants._LONGITUDE))
holder.map_icon.setColorFilter(Color.GRAY);
holder.map_icon.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if ( field.containsKey(Constants._LATITUDE) && field.containsKey(Constants._LONGITUDE)) {
Toast.makeText(context, "Center in Field Position", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, Constants.NOT_CENTRED, Toast.LENGTH_LONG).show();
}
}
});
return view;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean hasStableIds() {
return true;
}
/** Events **/
/** Holder Classes **/
private static class ChildHolder {
TextView title;
ImageView map_icon;
CheckBox contour;
}
private static class GroupHolder {
TextView title;
}
}
My Layouts.
Main xml. field_list.xml -> Layout for ExpandableListView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lin_layout_field_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ExpandableListView
android:id="#+id/field_expandable_list"
android:layout_width="match_parent"
android:layout_height="0dp" <- That's a SO advice, in order that children won't be croped. Originally wrap_content
android:layout_weight="1"
android:headerDividersEnabled="true"
android:divider="#color/metallic_silver"
android:dividerHeight="1dp">
</ExpandableListView>
</LinearLayout>
Group_client.xml -> Layout for each Group Item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/lin_layout_client_group"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/client_group_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="30dp"
android:text="Something"
android:textColor="#android:color/white"
android:textSize="16dp"
android:textStyle="normal" />
</LinearLayout>
</LinearLayout>
child_client.xml -> Layout for each Child Item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/lin_layout_client_child"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<CheckBox
android:id="#+id/client_child_checkbox"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0.05"
android:checked="true"
android:gravity="center_vertical|center" />
<TextView
android:id="#+id/client_child_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:padding="10dp"
android:text="FIELD_NAME"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#android:color/white"
android:layout_weight="0.90" />
<ImageView
android:id="#+id/client_child_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0.05"
android:layout_margin="5dp"
android:gravity="center_vertical|center"
android:src="#drawable/gmaps_icon_24" />
</LinearLayout>
</LinearLayout>
EDIT(2):
As said, it's no problem cause of Layouts or ClientAdapter, so that it works fine in this example
public class ClientActivity2 extends Activity{
private ExpandableListView client;
private ClientAdapter client_adapter;
private ArrayList children;
private ArrayList<String> groups;
private LayoutInflater inflater;
private LinearLayout lin_layout_probe;
private Context context;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.field_list);
context = getApplicationContext();
prepareData();
ExpandableListView client = (ExpandableListView)findViewById(R.id.field_expandable_list);
client_adapter = new ClientAdapter(context, groups, children);
client.setAdapter(client_adapter);
client.expandGroup(0);
}
private void prepareData() {
children = new ArrayList();
HashMap<String,Object> hm1 = new HashMap<String,Object>();
hm1.put(Constants._FIELDNAME,"Child1");
children.add(hm1);
HashMap<String,Object> hm2 = new HashMap<String,Object>();
hm2.put(Constants._FIELDNAME,"Child2");
children.add(hm2);
HashMap<String,Object> hm3 = new HashMap<String,Object>();
hm3.put(Constants._FIELDNAME,"Child3");
children.add(hm3);
groups = new ArrayList<String>();
groups.add("Group1");
}
}
Now it comes what confuses me...
If I test all(Adapter and the same calls) with a simple Activity, which has a clickable TextView at its main layout then works fine!
If I click this TextView then the ExpandableListView prompts with properly populated Group and Children and they are expandable/collapsable.
If I test like my last post hier,(ExpandableListView embedded in a ListView Item) so, the ExpandableListView prompts, if I click that the ExpandableListView of that Item
then the groups are populated but not the children. GetChildView gets never called!!!(I used LogCat, so I'm completely sure)
I have seen, many people had troubles with clicks in ExpandableListViews in ListViewItems, my case is different, I can perform that, my trouble is understanding, why with a TextView works fine that ExpandableListView Population via my custom BaseExpandableListAdapter but not in a ListView Item.
Solved
In my first level Adapter (An adapter for the first level ExpandableListView) I modified the getChildView Method
...
// Member Field
private ExpandableListView expandable_field_list;
...
#Override
public View getChildView(int groupPosition, int childPosition,boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if ( groupPosition == 1 ) {
if ( expandable_field_list == null ) {
expandable_field_list = new CustomExpandableListView(context);
// Here I initialize the second and third Level
client_adapter = new ClientAdapter(context, groups, children);
expandable_field_list.setAdapter(client_adapter);
} else {
client_adapter.notifyDataSetChanged();
}
convertView = expandable_field_list;
}
return convertView;
}
...
And CustomExpandableListView looks like this
public class CustomExpandableListView extends ExpandableListView {
private boolean expanded = true;
public CustomExpandableListView(Context context) {
super(context);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (isExpanded()) {
// View.MEASURED_SIZE_MASK represents the largest height possible.
int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
#Override
protected void onDetachedFromWindow() {
try {
super.onDetachedFromWindow();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
public void setIsExpanded(boolean expanded) {
this.expanded = expanded;
}
public boolean isExpanded() {
return expanded;
}
}
That is its aspect now as desired

Listview is not showing first entry

I am showing all files from server in listview.
Files on server are as follows:
binary.txt/erpTestBench/muneem.php/oglPrahova/permitCore/workOrderTestBench/
Listview is showing all files except binary.txt file.
My listview xml file is as follows:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:id="#+id/path"
android:layout_width="fill_parent"
android:textSize="12dp"
android:layout_height="wrap_content" android:background="#2377ff"/>
<ListView
android:id="#android:id/list"
android:cacheColorHint="#00000000"
android:layout_width="fill_parent"
android:layout_height="70dp"
android:layout_weight="0.85"
android:clickable="false"
android:textSize="30dp"
android:drawSelectorOnTop="false" android:background="#2f3fc8" android:layout_gravity="center"
android:dividerHeight="15dp"/>
<TextView
android:id="#android:id/empty"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="30dp"
android:text="No Data"
android:layout_weight="0.75"
android:background="#2f3fc8"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:paddingTop="6dp" android:paddingBottom="6dp" android:gravity="center|center_vertical"
android:id="#+id/linearLayout" android:background="#346684">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView1"
android:src="#drawable/power"
android:onClick="bt_Quit" android:layout_marginLeft="10dp" android:layout_marginRight="10dp"
android:layout_gravity="center"/>
<ImageView
android:layout_width="80dp"
android:layout_height="fill_parent"
android:id="#+id/imageView4"
android:src="#drawable/back"
android:onClick="back"
android:layout_marginLeft="10dp" android:layout_marginRight="10dp"/>
<ImageView
android:layout_width="71dp"
android:layout_height="fill_parent"
android:id="#+id/imageView2"
android:src="#drawable/home"
android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:onClick="home"/>
</LinearLayout>
</LinearLayout>
my java file is as follows:
public class serv extends ListActivity {
private String m_urlString="XXXXX";
// private String result;
private List<String> m_item = null;
private List<String> m_path = null;
private String m_root="XXXX";
private String m_result;
private TextView m_myPath;
static private String m_pos;
private String m_backposition;
private String m_fileURL;
int m_downloadedSize = 0;
int m_totalSize = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.file_chooser);
View v= findViewById(R.id.rowtext);
m_myPath = (TextView)findViewById(R.id.path);
m_fileURL="http://192.168.1.30/muneem/";
Http_connection f=new Http_connection();
f.execute("");
}
class Http_connection extends AsyncTask<String, Void, Void> {
private Exception exception;
protected Void doInBackground(String... urls)
{
try
{
URL url= new URL(m_urlString);
HttpURLConnection con=(HttpURLConnection)url.openConnection();
con.setRequestMethod("GET");
con.connect();
int statusCode=con.getResponseCode();
if (statusCode==HttpURLConnection.HTTP_OK){
BufferedReader in= new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
m_result="";
while ((line=in.readLine())!=null)
{
m_result=m_result+"\n"+line;
}
in.close();
con.disconnect();
runOnUiThread(new Runnable() {
#Override
public void run() {
getDir(m_urlString);
}
});
}
}
catch (MalformedURLException e)
{
// bundle.putString("Error","Problem with URL");
}
catch (IOException e)
{
// bundle.putString("Error","Problem with connection");
}
return null;
}
}
private void getDir(String dirPath)
{
String[] r=m_result.split("/");
m_myPath.setText("Location: " + dirPath);
m_item = new ArrayList<String>();
m_path = new ArrayList<String>();
for (int k=0;k<r.length;k++)
{
if (r[k].contains("."))
{
m_item.add(r[k]);
}
else
{
m_item.add(r[k]+"/");
}
}
ArrayAdapter<String> fileList =
new ArrayAdapter<String>(serv.this, R.layout.row, m_item);
setListAdapter(fileList);
}
Your data goes through a few steps before making it to the ListView, so the source of the problem could be in one of a few different steps. If you debug your code and check the value of m_result at the beginning of getDir(), you can determine where the problem is coming from. If the value is as expected, there's probably an issue in getDir(), whereas if there's a problem with the string, the issue is probably in doInBackground() (and easy to spot if you know what's wrong with the result, as it turned out).

Why am I getting a null pointer exception?

The title of this problem describes my problem. I have tried fixing this for a while and i am tired of searching and would like some help please. It used to work until I added the Handler and runner. I am trying to make an application that is a simple clock application that the user can set to any time that they want to. Whenever I go to run the application, it opens and then says it would not start properly. This is an activity that is set by another activity and then it changes the values it receives, it also displays these values in textviews.
package CoopFun.Clocks;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.TextView;
import android.content.Intent;
import android.app.Activity;
public class ClockMain extends Activity {
int Hours;
int Minutes;
int Seconds;
String TimeOfDayS;
TextView HoursMainV;
TextView MinutesMainV;
TextView SecondsMainV;
TextView TimeOfDayMainV;
Timer oneSecond;
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.clock_main);
requestWindowFeature(Window.FEATURE_NO_TITLE);
Bundle extras = getIntent().getExtras();
if (extras == null) {
return;
}
int Hour = extras.getInt("HoursS");
Hour = Hours;
int Minute = extras.getInt("MinutesS");
Minute = Minutes;
int Second = extras.getInt("SecondsS");
Second = Seconds;
String TimeOfDaySs = extras.getString("TimeOfDayS");
TimeOfDaySs = TimeOfDayS;
HoursMainV = (TextView) findViewById(R.id.HoursMainV);
HoursMainV.setText(""+Hour);
MinutesMainV = (TextView) findViewById(R.id.MinutesMainV);
MinutesMainV.setText(":"+Minute);
SecondsMainV = (TextView) findViewById(R.id.SecondsMainV);
SecondsMainV.setText(":"+Second);
TimeOfDayMainV = (TextView) findViewById(R.id.TimeOfDayMainV);
TimeOfDayMainV.setText(" "+TimeOfDaySs);
final Handler handler=new Handler();
final Runnable r = new Runnable()
{
public void run()
{
++Seconds;
if(Seconds == 60){
++Minutes;
Seconds = 0;
if(Minutes == 60) {
++Hours;
Minutes = 0;
if(Hours == 12){
if(TimeOfDayS.equals("AM")) {
TimeOfDayS = "PM";
} else{
TimeOfDayS = "AM";
}
Hours = 0;
}
}
}
HoursMainV.append(""+Hours);
if(Minutes <=9) {
MinutesMainV.append(":0"+Minutes);
} else {
MinutesMainV.append(":"+Minutes);
}
if(Seconds <=9) {
SecondsMainV.append(":0"+Seconds);
} else {
SecondsMainV.append(":"+Seconds);
}
TimeOfDayMainV.append(" " + TimeOfDayS);
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:textSize="50dip"
android:id="#+id/HoursMainV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="25dip"></TextView>
<TextView
android:textSize="50dip"
android:id="#+id/MinutesMainV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></TextView>
<TextView
android:textSize="50dip"
android:id="#+id/SecondsMainV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></TextView>
<TextView
android:textSize="50dip"
android:id="#+id/TimeOfDayMainV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></TextView>
</LinearLayout>
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="CoopFun.Clocks"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".Clock"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ClockMain">
</activity>
</application>
</manifest>
Thank you.
int Hour = extras.getInt("HoursS");
Hour = Hours;
int Minute = extras.getInt("MinutesS");
Minute = Minutes;
int Second = extras.getInt("SecondsS");
Second = Seconds;
String TimeOfDaySs = extras.getString("TimeOfDayS");
TimeOfDaySs = TimeOfDayS;
Change above code with this::
int Hour = extras.getInt("HoursS");
Hours = Hour;
int Minute = extras.getInt("MinutesS");
Minutes = Minute;
int Second = extras.getInt("SecondsS");
Seconds = Second;
String TimeOfDaySs = extras.getString("TimeOfDayS");
TimeOfDayS = TimeOfDaySs;
Simply, u were getting null pointer exception bcoz u were setting null values to Hour,Minute,Second and TimeOfDaySs and accessing them.
Cheers....!!!