I have a toggleButton that I wish to set an onTouchListener on. I am getting some errors however so I don't think I'm doing this right.
I have declared my button.
private ToggleButton pushBtn;
I have set my activity to implement View.onTouchListener.
public class InCallActivity extends SherlockFragmentActivity implements View.OnTouchListener {
In onCreate I have written:
pushBtn = (ToggleButton) findViewById(R.id.PTT_button3);
pushBtn.setOnTouchListener(this);
Then I have tried to use the listener in the class::
pushBtn.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event)
{
// if more than one call, change this code
int callId = 0;
for (SipCallSession callInfo : callsInfo)
{
callId = callInfo.getCallId();
Log.e(TAG, "" + callInfo.getCallId());
}
final int id = callId;
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
{
// press
pushBtn.setBackgroundResource(R.drawable.btn_blue_glossy);
pushBtn.setChecked(true);
OnDtmf(id, 17, 10);
OnDtmf(id, 16, 9);
return true;
}
case MotionEvent.ACTION_UP:
{
// release
pushBtn.setBackgroundResource(R.drawable.btn_lightblue_glossy);
pushBtn.setChecked(false);
OnDtmf(id, 18, 11);
OnDtmf(id, 18, 11);
return true;
}
default:
return false;
}
}
});
I have multiple errors, it says onTouch is not implemented, but I have done so?
Also I placed the listener in the class and it now complains about the method before it saying:
Syntax error on token "}", delete this token
But That was fine until I added the listener, does a listener have to be in a method or something?
At the end of my listener I get the error:
Syntax error, insert "}" to complete MethodBody
But I do now know why.
EDIT UPDATE
Here is my onCreate, I get a nullpointerexception:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//handler.setActivityInstance(this);
Log.d(THIS_FILE, "Create in call");
setContentView(R.layout.in_call_main);
SipCallSession initialSession = getIntent().getParcelableExtra(SipManager.EXTRA_CALL_INFO);
synchronized (callMutex) {
callsInfo = new SipCallSession[1];
callsInfo[0] = initialSession;
}
bindService(new Intent(this, SipService.class), connection, Context.BIND_AUTO_CREATE);
prefsWrapper = new PreferencesProviderWrapper(this);
// Log.d(THIS_FILE, "Creating call handler for " +
// callInfo.getCallId()+" state "+callInfo.getRemoteContact());
powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE,
"com.csipsimple.onIncomingCall");
wakeLock.setReferenceCounted(false);
takeKeyEvents(true);
// Cache findViews
mainFrame = (ViewGroup) findViewById(R.id.mainFrame);
inCallControls = (InCallControls) findViewById(R.id.inCallControls);
inCallAnswerControls = (InCallAnswerControls) findViewById(R.id.inCallAnswerControls);
activeCallsGrid = (InCallInfoGrid) findViewById(R.id.activeCallsGrid);
heldCallsGrid = (InCallInfoGrid) findViewById(R.id.heldCallsGrid);
pushBtn = (ToggleButton) findViewById(R.id.PTT_button3);
//pushBtn.setOnTouchListener((OnTouchListener) this);
attachVideoPreview();
inCallControls.setOnTriggerListener(this);
inCallAnswerControls.setOnTriggerListener(this);
if(activeCallsAdapter == null) {
activeCallsAdapter = new CallsAdapter(true);
}
activeCallsGrid.setAdapter(activeCallsAdapter);
if(heldCallsAdapter == null) {
heldCallsAdapter = new CallsAdapter(false);
}
heldCallsGrid.setAdapter(heldCallsAdapter);
ScreenLocker lockOverlay = (ScreenLocker) findViewById(R.id.lockerOverlay);
lockOverlay.setActivity(this);
lockOverlay.setOnLeftRightListener(this);
/*
middleAddCall = (Button) findViewById(R.id.add_call_button);
middleAddCall.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
onTrigger(ADD_CALL, null);
}
});
if (!prefsWrapper.getPreferenceBooleanValue(SipConfigManager.SUPPORT_MULTIPLE_CALLS)) {
middleAddCall.setEnabled(false);
middleAddCall.setText(R.string.not_configured_multiple_calls);
}
*/
// Listen to media & sip events to update the UI
registerReceiver(callStateReceiver, new IntentFilter(SipManager.ACTION_SIP_CALL_CHANGED));
registerReceiver(callStateReceiver, new IntentFilter(SipManager.ACTION_SIP_MEDIA_CHANGED));
registerReceiver(callStateReceiver, new IntentFilter(SipManager.ACTION_ZRTP_SHOW_SAS));
proximityManager = new CallProximityManager(this, this, lockOverlay);
keyguardManager = KeyguardWrapper.getKeyguardManager(this);
dialFeedback = new DialingFeedback(this, true);
if (prefsWrapper.getPreferenceBooleanValue(SipConfigManager.PREVENT_SCREEN_ROTATION)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
if (quitTimer == null) {
quitTimer = new Timer("Quit-timer");
}
useAutoDetectSpeaker = prefsWrapper.getPreferenceBooleanValue(SipConfigManager.AUTO_DETECT_SPEAKER);
applyTheme();
proximityManager.startTracking();
inCallControls.setCallState(initialSession);
inCallAnswerControls.setCallState(initialSession);
pushBtn.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
//if more than one call, change this code
int callId = 0;
for (SipCallSession callInfo : callsInfo) {
callId = callInfo.getCallId();
Log.e(TAG, ""+callInfo.getCallId());
}
final int id= callId;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
//press
pushBtn.setBackgroundResource(R.drawable.btn_blue_glossy);
pushBtn.setChecked(true);
OnDtmf(id, 17, 10);
OnDtmf(id, 16, 9);
return true;
}
case MotionEvent.ACTION_UP: {
//release
pushBtn.setBackgroundResource(R.drawable.btn_lightblue_glossy);
pushBtn.setChecked(false);
OnDtmf(id, 18, 11);
OnDtmf(id, 18, 11);
return true;
}
default:
return false;
}
}
});
}
The line with the nullpointer 250 is pushBtn.setOnTouchListener(new OnTouchListener() {
You should add '}' on closing touch method.
Eclipse sometimes makes some mistakes by itself.
You're code seems right, try to cut all of your code and then paste it again in the same position.
Also try to remove all of the import at the beginning of the class and then reimporting everything by pressing
ctrl + SHIFT + o (cmd+shift+o on a mac)
another solution is to put a
return false;
at the very end of the onTouch method
Related
Problem:
I have an existing app that I would like to implement Android 6.0's Runtime Permissions on. I have read a lot of different things on Runtime Permissions, but I just can't seem to wrap my head around all the different snippets. Nothing I have found actually shows how to implement this into an existing Activity.
Other Points
When I run my existing application targeting SDK v23 I get the permission error as expected, but the permission error I get is not even a permission that I am requesting. I have the SEND_SMS permission in the Manifest file, but the error I am getting is for READ_SMS. My app runs fine on pre 6.0 without READ_SMS.
I would like the my app to ask for permission as soon as the app is launched because the sole purpose of the app is the send an SMS message, so without that permission there is no other use for the app.
Questions:
How would I implement Runtime Permissions for SEND_SMS into my existing Activity as soon as the app is launched?
Does the handling of these permission need to run in a background thread?
Do I also need permissions for READ_SMS since that is the permission error that it is giving (even though that permission has never been used on my app)?
My Existing Activity:
public class MainActivity extends Activity implements OnClickListener {
SimpleCursorAdapter mAdapter;
AutoCompleteTextView txtContract;
EditText txtTrip;
EditText txtDate;
Button btnSend;
Button btnUpdate;
String today;
String SENT = "SMS_SENT";
String DELIVERED = "SMS_DELIVERED";
private static final String API_KEY = "abcxyz";
private static final String CONTRACT_REGEX = "^([a-zA-Z0-9_-]){5}$";
private static final String TRIP_REGEX = "^([a-zA-Z0-9_-]){1,10}$";
private static final String DATE_REGEX = "^\\d{2}\\/\\d{2}\\/\\d{4}$";
private static final String PHONE_NUMBER = "1234567890";
private static final String DATE_FORMAT = "MM/dd/yyyy";
private BroadcastReceiver sendBroadcastReceiver;
private BroadcastReceiver deliveryBroadcastReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// TODO - IMPLEMENT RUNTIME PERMISSIONS FOR ANDROID >= 6.0
try {
// Initialize Views
txtContract = (AutoCompleteTextView) findViewById(R.id.txtContract);
txtTrip = (EditText) findViewById(R.id.txtTrip);
txtDate = (EditText) findViewById(R.id.txtDate);
btnSend = (Button) findViewById(R.id.btnSend);
btnUpdate = (Button) findViewById(R.id.btnUpdate);
// Set Listeners
txtDate.setOnClickListener(this);
btnSend.setOnClickListener(this);
btnUpdate.setOnClickListener(this);
// Set Date To Today And Format
final Calendar td = Calendar.getInstance();
int tYear = td.get(Calendar.YEAR);
int tMonth = td.get(Calendar.MONTH);
int tDay = td.get(Calendar.DAY_OF_MONTH);
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH);
td.set(tYear, tMonth, tDay);
today = sdf.format(td.getTime());
txtDate.setText(today);
// Check If Device Is Capable Of Sending SMS
PackageManager pm = this.getPackageManager();
if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) &&
!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
Toast.makeText(this, "Sorry, your device probably can't send SMS...",
Toast.LENGTH_SHORT).show();
}
// Send Receiver
sendBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "Requesting trip...", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(getBaseContext(), "Generic failure", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(getBaseContext(), "No service", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(getBaseContext(), "Radio off", Toast.LENGTH_SHORT).show();
break;
}
}
};
// Delivery Receiver
deliveryBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "Trip request successful.", Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
Toast.makeText(getBaseContext(), "Trip request failed.", Toast.LENGTH_SHORT).show();
break;
}
}
};
// Register Receivers
registerReceiver(deliveryBroadcastReceiver, new IntentFilter(DELIVERED));
registerReceiver(sendBroadcastReceiver , new IntentFilter(SENT));
// Set Up Adapter For Autocomplete
initializeAutoCompleteAdapter();
}
catch (Exception ex) {
Toast.makeText(this, "Error in MainActivity.onCreate: " + ex.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onDestroy() {
unregisterReceiver(sendBroadcastReceiver);
unregisterReceiver(deliveryBroadcastReceiver);
super.onDestroy();
}
// Auto Complete Adapter
public void initializeAutoCompleteAdapter() {
// Set Database Handler
final DBHelper DBHelper = new DBHelper(getBaseContext());
// Set Up Adapter For Autocomplete (This does not run on the main UI thread)
mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, null,
new String[] { "contract" },
new int[] {android.R.id.text1},
0);
txtContract.setAdapter(mAdapter);
mAdapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() {
#Override
public CharSequence convertToString(Cursor cursor) {
final int colIndex = cursor.getColumnIndexOrThrow("contract");
return cursor.getString(colIndex);
}
});
mAdapter.setFilterQueryProvider(new FilterQueryProvider() {
#Override
public Cursor runQuery(CharSequence description) {
String strContract = txtContract.getText().toString();
return DBHelper.getContract(strContract);
}
});
}
// OnClickListener Handler
#Override
public void onClick(View v) {
// Handle Clicked View
switch (v.getId()) {
// Date Field
case R.id.txtDate:
// Get Current Date
final Calendar c = Calendar.getInstance();
c.set(c.get(Calendar.YEAR),c.get(Calendar.MONTH),c.get(Calendar.DAY_OF_MONTH),0,0,0);
int mYear = c.get(Calendar.YEAR);
int mMonth = c.get(Calendar.MONTH);
int mDay = c.get(Calendar.DAY_OF_MONTH);
// Set Up DatePicker Dialog
DatePickerDialog datePickerDialog = new DatePickerDialog(this,
new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int month, int day) {
// Define A New Calendar For Formatting
final Calendar cf = Calendar.getInstance();
// Format Selected Date
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH);
cf.set(year,month,day);
String selectedDate = sdf.format(cf.getTime());
// Add Selected Date To EditText Field
txtDate.setText(selectedDate);
}
}, mYear, mMonth, mDay);
// Set Max Date
c.add(Calendar.DATE, 2);
c.add(Calendar.SECOND, -1);
datePickerDialog.getDatePicker().setMaxDate(c.getTimeInMillis());
// Set Min Date
c.add(Calendar.DAY_OF_MONTH,-5);
c.add(Calendar.SECOND, 1);
datePickerDialog.getDatePicker().setMinDate(c.getTimeInMillis());
// Display DatePicker
datePickerDialog.show();
break;
// Submit Button
case R.id.btnSend:
Boolean rval = true;
if (!Validation.isValid(txtContract, CONTRACT_REGEX, "Invalid Contract #", true)) rval = false;
if (!Validation.isValid(txtTrip, TRIP_REGEX, "Invalid Trip #", true)) rval = false;
if (!Validation.isValid(txtDate, DATE_REGEX, "Invalid Date", true)) rval = false;
if(rval) {
new ValidateAndSend(this).execute();
}
break;
// Update Contract DB
case R.id.btnUpdate:
TelephonyManager tMgr = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
new POSTAsync(this).execute(API_KEY, mPhoneNumber);
break;
}
}
// Validate And Send
class ValidateAndSend extends AsyncTask<String, String, Boolean>{
private final WeakReference<MainActivity> MainActivityWeakRef;
public ValidateAndSend(MainActivity mainActivity) {
super();
this.MainActivityWeakRef = new WeakReference<>(mainActivity);
}
// Define Variables
String strContract = txtContract.getText().toString();
String strTrip = txtTrip.getText().toString();
String strDate = txtDate.getText().toString();
String strMessage = strContract.concat("|").concat(strTrip).concat("|").concat(strDate);
Boolean rval = true;
#Override
protected void onPreExecute() {
}
#Override
protected Boolean doInBackground(String... contract) {
DBHelper DBHelper = new DBHelper(MainActivity.this);
if (DBHelper.validateContract(strContract) < 1) rval = false;
return rval;
}
#Override
protected void onPostExecute(Boolean rval){
if(rval){
// Hide Keyboard
View view = MainActivity.this.getCurrentFocus();
if(view != null){
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
if (MainActivityWeakRef.get() != null && !MainActivityWeakRef.get().isFinishing()) {
// Confirm Details
AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
alert.setTitle("Confirm Trip");
alert.setMessage("CONTRACT: " + strContract + "\nTRIP: " + strTrip + "\nDATE: " + strDate);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Send SMS
sendSMS(PHONE_NUMBER, strMessage);
// Clear Fields
txtContract.setText("");
txtTrip.setText("");
txtDate.setText(today);
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Cancelled
}
});
// Show Alert
alert.show();
}
}
else{
txtContract.setError("Invalid contract #");
Toast.makeText(MainActivity.this, "You may need to update contracts.",
Toast.LENGTH_LONG).show();
}
}
}
// Send SMS
private void sendSMS(String phoneNumber, String message) {
String SENT = "SMS_SENT";
String DELIVERED = "SMS_DELIVERED";
PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0);
PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
}
}
The runtime permission model for Android 6.0 is mainly divided into part
1. Checking Permission
2. Requesting Permission
you can create two method for this thing in your activity, As follow
Check Permission
private boolean checkPermission(){
int result = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_SMS);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
Request Permission
private void requestPermission(){
if (ActivityCompat.shouldShowRequestPermissionRationale(activity,Manifest.permission.READ_SMS)){
Toast.makeText(context,"Read Sms Allowed.",Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.READ_SMS},PERMISSION_REQUEST_CODE);
}
}
Last but not least you need to override the onRequestPermissionsResult method
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Snackbar.make(view,"Permission Granted, Now you can access SMS.",Snackbar.LENGTH_LONG).show();
} else {
Snackbar.make(view,"Permission Denied, You cannot access SMS.",Snackbar.LENGTH_LONG).show();
}
break;
}
}
as you asked do i need to run this in thread .. answer is No Just do this in main thread
If you want to do less code then, please use Dexter is an Android library that simplifies the process of requesting permissions at runtime.
I have a problem closing my game after the last player close the last match. My turn scheme is:
Player A
Player B
Player B
Player A
Player A
Player B
The game works well but in turn "6" when player B try to close the match, player A always see the matsh as "my turn" and not as "completed"
here there is the code thar rules turns and game ended:
#Override
public void onGameEnd(final NMXGameData updatedData) {
super.onGameEnd(updatedData);
if (updatedData.getMatchNumber() == NMXGameConfig.MATCHES) {
boolean iWin = updatedData.getResultPoints()[1] > updatedData.getResultPoints()[0];
boolean tile = updatedData.getResultPoints()[1] == updatedData.getResultPoints()[0];
ParticipantResult opponentParticipantResult;
ParticipantResult myParticipantResult;
if (tile) {
opponentParticipantResult = new ParticipantResult(getOpponentId(), ParticipantResult.MATCH_RESULT_TIE, 1);
myParticipantResult = new ParticipantResult(getCurrentPlayerId(), ParticipantResult.MATCH_RESULT_TIE, 1);
} else {
if (iWin) {
opponentParticipantResult = new ParticipantResult(getOpponentId(), ParticipantResult.MATCH_RESULT_LOSS, 2);
myParticipantResult = new ParticipantResult(getCurrentPlayerId(), ParticipantResult.MATCH_RESULT_WIN, 1);
} else {
opponentParticipantResult = new ParticipantResult(getOpponentId(), ParticipantResult.MATCH_RESULT_WIN, 1);
myParticipantResult = new ParticipantResult(getCurrentPlayerId(), ParticipantResult.MATCH_RESULT_LOSS, 2);
}
}
ArrayList<ParticipantResult> participantResultArrayList = new ArrayList<>();
participantResultArrayList.add(opponentParticipantResult);
participantResultArrayList.add(myParticipantResult);
Games.TurnBasedMultiplayer.finishMatch(getApiClient(), match.getMatchId(), new Gson().toJson(updatedData).getBytes(), opponentParticipantResult, myParticipantResult).setResultCallback(new ResultCallback<TurnBasedMultiplayer.UpdateMatchResult>() {
#Override
public void onResult(TurnBasedMultiplayer.UpdateMatchResult updateMatchResult) {
finish();
}
});
} else if (updatedData.getMatchNumber() < NMXGameConfig.MATCHES) {
if (getNextPlayerIndex(updatedData.getMatchNumber()) != getNextPlayerIndex(updatedData.getMatchNumber() - 1)) {
Games.TurnBasedMultiplayer.takeTurn(getApiClient(), match.getMatchId(), new Gson().toJson(updatedData).getBytes(), getNextParticipantId());
} else {
Games.TurnBasedMultiplayer.takeTurn(getApiClient(), match.getMatchId(), new Gson().toJson(updatedData).getBytes(), getCurrentPlayerId());
startActivity(startNewOnlineGameIntent(this, updatedData, match.getMatchId()));
}
finish();
}
}
private String getCurrentPlayerId() {
return match.getParticipantId(Games.Players.getCurrentPlayerId(getApiClient()));
}
private String getOpponentId() {
for (String id : match.getParticipantIds()) {
if (!id.equals(getCurrentPlayerId())) {
return id;
}
}
return null;
}
private int getNextPlayerIndex(int nextRoundIndex) {
nextRoundIndex = nextRoundIndex + 1;
return (nextRoundIndex / 2) % 2;
}
I finally figured it out.
I don't know if that is the desired behavior but when in round 6 player_B calls:
Games.TurnBasedMultiplayer.finishMatch(getApiClient(), match.getMatchId(), new Gson().toJson(updatedData).getBytes(), opponentParticipantResult, myParticipantResult).setResultCallback(new ResultCallback<TurnBasedMultiplayer.UpdateMatchResult>() {
#Override
public void onResult(TurnBasedMultiplayer.UpdateMatchResult updateMatchResult) {
finish();
}
});
The turn goes to player_A that see that match as "my turn". At this point player A must call Games.TurnBasedMultiplayer.finishMatch(getApiClient(), match.getMatchId()) (without playing a real game) and the game is completed for both players
I want to get the orientation of my phone and I have using this code that I find lot of people using it. this is the code
public void onSensorChanged(SensorEvent event) {
//if the data sensor is unreliabel
if(event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
return;
//gets the value
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
gravity = event.values.clone();
break;
case Sensor.TYPE_MAGNETIC_FIELD:
geomag = event.values.clone();
break;
}
getOrientation();
}
private void getOrientation(){
//if gravity n geomag have value, find the rotation matrix
if(gravity != null && geomag != null){
//check the rotation matrix found
boolean success = SensorManager.getRotationMatrix(inR, I, gravity, geomag);
if(success){
SensorManager.getOrientation(inR, orientVals);
azimuth = Math.toDegrees(orientVals[0]);
TextView azi = (TextView) findViewById(R.id.textAzi);
azi.setText("azi : " + azimuth);
}
TextView cek = (TextView) findViewById(R.id.cek);
cek.setText("rotation: "+success);
}
but why the getrotationmatrix always return to false?
where is the problem?
I've try again and get the solution
but I change the code to become like below
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
for(int i=0; i<3; i++){
accelValues[i] = event.values[i];
}
if(compassValues[0] != 0)
ready = true;
break;
case Sensor.TYPE_MAGNETIC_FIELD:
for(int i=0; i<3; i++){
compassValues[i] = event.values[i];
}
if(accelValues[2] != 0)
ready = true;
break;
}
if(!ready)
return;
boolean cek = SensorManager.getRotationMatrix(inR, inclineMatrix, accelValues, compassValues);
if(cek){
SensorManager.getOrientation(inR, prefValues);
mInclination = SensorManager.getInclination(inclineMatrix);
//display every 30th values
if(counter++ % 30 == 0){
//do your code, what you want to do to the result
counter = 1;
}
}
and everything work well
Make sure that you have registered your listeners to listen to the accelerometer, magmetic field and gyro (optional). You do this in the onResume method. If you forget to do this you will get "false" return value when calling getRotationMatrix.
I hope this helps!
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
// do more staff here..
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(
this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL );
mSensorManager.registerListener(
this,
mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_NORMAL );
mSensorManager.registerListener(
this,
mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE),
SensorManager.SENSOR_DELAY_NORMAL );
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
The problem is with this part of code:
if(event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
return;
For accelerometer event.accuracy return SensorManager.SENSOR_STATUS_UNRELIABLE that is why gravity is always null.
Is it possible to implement a fast forward button using the onLongClick button event?
EDIT
i used runnable inside the onlongclicklistner and adding the code for reference who needs :)
Button.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
final Runnable r = new Runnable()
{
public void run()
{//do the forwarding logic here
if(Button.isPressed()){
Button.postDelayed(this, 1000); //delayed for 1 sec
}else{
Button.postInvalidate();
Button.invalidate();
}
}
};
Button.post(r);
return true;
}
});
In your onLongClick event, set a member variable (example: mShouldFastForward) to true.
In the rest of your code (perhaps each frame played?) check if mShouldFastForward == true; if so, perform a fast-forward on that frame.
Use an onTouch event to capture the MotionEvent.ACTION_UP to set mShouldFastForward to false.
I have done it in this project (the project is not finished (ie polished) but fast forward works):
https://bitbucket.org/owentech/epileptic-gibbon-android
Take a look at playerfragment.java :
I handle this by using Threads to fast forward the mediaplayer.
Example code from project:
/*******************************/
/* Fast-Forward button actions */
/*******************************/
ffbutton.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
switch (event.getAction() ) {
case MotionEvent.ACTION_DOWN:
arrays.fastforwardpressed = true;
FastForwardThread newFFThread = new FastForwardThread();
arrays.fastforwardfrom = mp.getCurrentPosition();
arrays.fastforwardto = arrays.fastforwardfrom;
newFFThread.start();
break;
case MotionEvent.ACTION_UP:
arrays.fastforwardpressed = false;
mp.seekTo(arrays.fastforwardto);
break;
}
return true;
}
});
public class FastForwardThread extends Thread
{
public FastForwardThread()
{
super("FastForwardThread");
}
public void run()
{
while (arrays.fastforwardpressed == true)
{
arrays.fastforwardto = arrays.fastforwardto + 10000;
int fastforwardseconds = arrays.fastforwardto / 1000;
int hours = fastforwardseconds / 3600, remainder = fastforwardseconds % 3600, minutes = remainder / 60, seconds = remainder % 60;
String Hours = Integer.toString(hours);
String Minutes = Integer.toString(minutes);
String Seconds = Integer.toString(seconds);
if (Hours.length() == 1)
{
Hours = "0" + Hours;
}
if (Minutes.length() == 1)
{
Minutes = "0" + Minutes;
}
if (Seconds.length() == 1)
{
Seconds = "0" + Seconds;
}
arrays.formattedfftime = Hours + ":" + Minutes + ":" + Seconds;
fastforwardHandler.sendEmptyMessage(0);
try
{
sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
Okay so I am having a problem getting my app to work. Basically I have an game that needs to get a few pictures and Strings from the user. I have an opening screen (OpeningScreen) that acts as a splash screen that opens up the menu (MenuScreen). From there the user can pick to go to the game or go to the activity that shows the current pictures (PickScreen). The user can go to that activity and from there open up another activity that gives a larger version of the picture they currently have picked or a default picture (PicOne). Here the user has the option to take a new picture and change the current Strings. For the most part all of it works great. My problem occurs when:
After the user picks a picture and backs out of the app. The next time they open it, it will force close either when I go back to PickScreen or after I press done after taking a new picture and sometimes when I go to PicOne activity. It does not do the same thing everytime, it just crashes at one of those points.
The other issue happens when I change the 3 String names. After pressing save and going back to PickScreen, the app crashes when going back to PicOne or if I back out of the app crashes when going from MenuScreen to PickScreen.
I know this is a lot of code to look at, but I have spent a lot of time looking around and getting code from different places for this app and I am at a point that I cannot figure out. I figure there are many people with more knowledge than me out there, so I am asking for your help. I know that you cannot just ask a question without showing you have been doing any work, so here it is.
Why does may app work perfectly once and then crash in various spots the second time in? By the way it does work fine after the force close, again only once. And why does it force close when I change the Strings?
Thanks everyone!!
The PicOne Class
public class PicOne extends Activity implements OnClickListener {
ImageView iv;
EditText c1, c2, c3;
Button cam, save;
Bitmap bit, bmp,other;
Intent i;
Uri uriSavedImage;
String imageFilePath10 = "", name1="", name2="", name3="";
final static int cameraData = 0;
boolean CAMERA;
int camORgal10 = 0;
SharedPreferences gameData;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.picone);
CAMERA = false;
iv = (ImageView)findViewById(R.id.picIV);
cam = (Button)findViewById(R.id.camButton);
save = (Button)findViewById(R.id.savebut);
e1 = (EditText)findViewById(R.id.Enter1);
e2 = (EditText)findViewById(R.id.Enter2);
e3 = (EditText)findViewById(R.id.Enter3);
cam.setOnClickListener(this);
save.setOnClickListener(this);
}
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId())
{
//camera
case R.id.camButton:
camORgal10 = 1;
i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "MySpot");
imagesFolder.mkdirs(); // <----
String fileName = "image_1.PNG";
File output = new File(imagesFolder, fileName);
uriSavedImage = Uri.fromFile(output);
i.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivityForResult(i, cameraData);
break;
case R.id.savebut:
CAMERA = true;
name1 = e1.getText().toString();
name2 = e2.getText().toString();
name3 = e3.getText().toString();
SharedPreferences.Editor editor = gameData.edit();
editor.putInt("NUM10CAMGAL", camORgal10);
editor.putString("NUM10NAME1", name1);
editor.putString("NUM10NAME2", name2);
editor.putString("NUM10NAME3", name3);
editor.commit();
Intent goPT = new Intent(this, PickScreen.class);
goPT.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
goPT.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
finish();
startActivity(goPT);
break;
}
}
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_BACK)
{
CAMERA = true;
name1 = e1.getText().toString();
name2 = e2.getText().toString();
name3 = e3.getText().toString();
SharedPreferences.Editor editor = gameData.edit();
editor.putInt("NUM10CAMGAL", camORgal10);
editor.putString("NUM10NAME1", name1);
editor.putString("NUM10NAME2", name2);
editor.putString("NUM10NAME3", name3);
editor.commit();
Intent goPT = new Intent(this, PickScreen.class);
goPT.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
goPT.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
finish();
startActivity(goPT);
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == cameraData)
{
if(resultCode == RESULT_OK && data.hasExtra("data"))
{
bmp = (Bitmap) data.getExtras().get("data");
iv.setImageBitmap(bmp);
}
else if (resultCode == RESULT_CANCELED)
{
Toast.makeText(getApplicationContext(), "Cancelled",Toast.LENGTH_SHORT).show();
}
}
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
if(OpeningScreen.isEXIT)
{
finish();
}
gameData = getSharedPreferences(MenuScreen.MYFOLDER, 0);
name1 = slotData.getString("NUM10NAME1", "one");
name2 = slotData.getString("NUM10NAME2", "two");
name3 = slotData.getString("NUM10NAME3", "three");
e1.setText(name1);
e2.setText(name2);
e3.setText(name3);
camORgal10 = gameData.getInt("NUM10CAMGAL", 0);
if(camORgal10 == 0)
{
bit = BitmapFactory.decodeResource(getResources(), R.drawable.red);
}
else if(camORgal10 == 1)
{
File imgFile = new File(Environment.getExternalStorageDirectory() + "/MySpot/image_1.PNG");
if(imgFile.exists())
{
bit = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
}
else
{
bit = BitmapFactory.decodeResource(getResources(), R.drawable.red);
}
}
else
{
bit = BitmapFactory.decodeResource(getResources(), R.drawable.red);
}
iv.setImageBitmap(bit);
super.onResume();
}
}
OpeningScreen
public class OpeningScreen extends Activity {
/** Called when the activity is first created. */
public static boolean isEXIT = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
isEXIT = false;
Thread timer = new Thread(){
public void run(){
try{
sleep(2500);
} catch(InterruptedException e){
} finally{
Intent toMenu = new Intent(getApplicationContext(), MenuScreen.class);
toMenu.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//toMenu.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
finish();
startActivity(toMenu);
}
}
};
timer.start();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
finish();
super.onPause();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
if(isEXIT)
{
finish();
}
super.onResume();
}
}
MenuScreen
public class MenuScreen extends Activity implements OnClickListener {
float x,y;
int camORgal = 0;
ImageButton play, edit, more;
Intent i;
public static String MYFOLDER = "GAMEDATA";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.menu);
play = (ImageButton)findViewById(R.id.IBplay);
edit = (ImageButton)findViewById(R.id.IBedit);
more = (ImageButton)findViewById(R.id.IBmore);
play.setOnClickListener(this);
edit.setOnClickListener(this);
more.setOnClickListener(this);
}
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_BACK)
{
OpeningScreen.isEXIT = true;
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId())
{
case R.id.IBplay:
i = new Intent(getApplicationContext(), TheGame.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
startActivity(i);
break;
case R.id.IBedit:
i = new Intent(this, PickScreen.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
startActivity(i);
break;
case R.id.IBmore:
break;
}
}
}
PickScreen
public class PickScreen extends Activity implements OnClickListener {
Button bPic1, bPic2, bPic3;
ImageView ivpic3,ivpic2, ivpic1;
TextView TVpic3a, TVpic3b, TVpic3c, TVpic2a, TVpic2b, TVpic2c, TVpic1a, TVpic1b, TVpic1c;
Intent pageMove;
SharedPreferences gameData;
int camORgal10 = 0;
String threeNamea = "", threeNameb = "", threeNamec = "", twoNamea = "", twoNameb = "", twoNamec = "", oneNamea = "", oneNameb = "", oneNamec = "";
Bitmap bmp1, bmp2,bmp3;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.paytable);
intitializeThings();
}
public void intitializeThings()
{
bPic1 = (Button)findViewById(R.id.pic1but);
bPic2 = (Button)findViewById(R.id.pic2but);
bPic3 = (Button)findViewById(R.id.pic3but);
ivpic3 = (ImageView)findViewById(R.id.ivpic3a);
ivpic2 = (ImageView)findViewById(R.id.ivpic2a);
ivpic1 = (ImageView)findViewById(R.id.ivpic1a);
TVpic3a = (TextView)findViewById(R.id.pic3TVa);
TVpic3b = (TextView)findViewById(R.id.pic3TVb);
TVpic3c = (TextView)findViewById(R.id.pic3TVc);
TVpic2a = (TextView)findViewById(R.id.pic2TVa);
TVpic2b = (TextView)findViewById(R.id.pic2TVb);
TVpic2c = (TextView)findViewById(R.id.pic2TVc);
TVpic1a = (TextView)findViewById(R.id.pic1TVa);
TVpic1b = (TextView)findViewById(R.id.pic1TVb);
TVpic1c = (TextView)findViewById(R.id.pic1TVc);
bPic1.setOnClickListener(this);
bPic2.setOnClickListener(this);
bPic3.setOnClickListener(this);
}
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId())
{
case R.id.pic1but:
pageMove = new Intent(getApplicationContext(), PicOne.class);
pageMove.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pageMove.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
//pageMove.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
finish();
startActivity(pageMove);
break;
case R.id.pic2but:
pageMove = new Intent(getApplicationContext(), PicTwo.class);
pageMove.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//pageMove.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(pageMove);
finish();
break;
case R.id.pic3but:
pageMove = new Intent(getApplicationContext(), PicThree.class);
pageMove.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//pageMove.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(pageMove);
finish();
break;
}
}
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_BACK)
{
Intent goOP = new Intent(this, MenuScreen.class);
goOP.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
goOP.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
finish();
startActivity(goOP);
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
gameData = getSharedPreferences(MenuScreen.MYFOLDER, 0);
oneNamea = gameData.getString("NUM10NAME1", "one");
oneNameb = gameData.getString("NUM10NAME2", "two");
oneNamec = gameData.getString("NUM10NAME3", "three");
camORgal10 = gameData.getInt("NUM10CAMGAL", 0);
if(camORgal10 == 1)
{
File pic1 = new File(Environment.getExternalStorageDirectory() + "/MySpot/image_1.PNG");
if(pic1.exists())
{
bmp1 = BitmapFactory.decodeFile(pic1.getAbsolutePath());
}
else
{
bmp1 = BitmapFactory.decodeResource(getResources(), R.drawable.red);
}
}
else if(camORgal10 == 0)
{
bmp1 = BitmapFactory.decodeResource(getResources(), R.drawable.red);
}
else
{
bmp1 = BitmapFactory.decodeResource(getResources(), R.drawable.red);
}
File pic2 = new File(Environment.getExternalStorageDirectory() + "/MySpot/image_2.PNG");
File pic3 = new File(Environment.getExternalStorageDirectory() + "/MySpot/image_3.PNG");
if(pic2.exists())
{
bmp2 = BitmapFactory.decodeFile(pic2.getAbsolutePath());
}
else
{
bmp2 = BitmapFactory.decodeResource(getResources(), R.drawable.purple);
}
if(pic3.exists())
{
bmp3 = BitmapFactory.decodeFile(pic3.getAbsolutePath());
}
else
{
bmp3 = BitmapFactory.decodeResource(getResources(), R.drawable.green);
}
ivpic3.setImageBitmap(bmp3);
ivpic2.setImageBitmap(bmp2);
ivpic1.setImageBitmap(bmp1);
TVpic1a.setText(oneNamea);
TVpic1b.setText(oneNameb);
TVpic1c.setText(oneNamec);
}
}
Logcat will give you a stack trace, and then use debug to pinpoint the place where it's crashing. Debugging a modern application by reading through code, especially OOP code, is nearly impossible.
This was probably caused by the fact the AOS does not closes apps really but you might think is does. So on the next start AOS doesn't start your app "from the scratch" but it raises your undead cached app. And since your logic wasn't expected that your app crashes. I'm pretty sure it starts OK once again right after the crash but the next start once again crashes -> the loop. So to avoid that use System.exit(0) (most advanced devs gonna say its a bad practice) to ensure your app wont became a zombie OR change the logic of your app so it wont crash on the next start cuz the main activity is still there.