When I download,click on pause,but there isn't respond.
I don't konw how to description specific,in fact it is meaning stop,but really can't realize.
the code
public void onClick(View v) {
[color=#FF0000]if (flag == 0){//click mark[/color]
can't display,the red is only a mark.
code as follows
holder.btns .setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
[color=#FF0000]if (flag == 0){//judge the click mark[/color]
holder.ratingBarScore.setVisibility(View.GONE);
holder.pro.setVisibility(View.VISIBLE);
holder.textView.setVisibility(View.VISIBLE);
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
}else {
// Toast.makeText(this, "there is no SD card", 1000).show();
Log.v("wjp", "7889900");
}
final String downloadUrl =(String)v.getTag();
Thread thread = new Thread(){
int count = 0;
public void run(){
Log.v("ccf", "onClick");
try {
downLoadFile(context, downloadUrl, gameName, holder);
openFile(context, new File("/sdcard/9twan/"+ gameName +".apk"));
if(!WebHelper.REGISTER_FLAG){
Log.v("GamesInfoListAdapter", "WebHelper.REGISTER_FLAG == false");
String imei, mac, mobile_number, model, brand;
boolean flag;
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
imei = tm.getDeviceId();
if(imei == null){
imei = "CUSTOM" + WebHelper.generateRandomIMEIString(15);
}
mac = null;
// mac = tm.getDeviceId();
if(mac == null){
mac = "CUSTOM" + WebHelper.generateRandomMacString(17);
}
mobile_number = tm.getLine1Number();
model = tm.getLine1Number();
brand = tm.getLine1Number();
flag = WebHelper.regDevice(context, "install", imei, mac, mobile_number, model, brand);
if(flag){
WebHelper.REGISTER_FLAG = true;
Log.v("GamesInfoListAdapter", "WebHelper.REGISTER_FLAG == true");
}
}
}catch (Exception e){
e.printStackTrace();
}
}
};
Log.v("wjp", "running"+thread.getName());
thread.start();
Toast.makeText(context, "begin to download" + gameName, 0).show();
holder.btns.setBackgroundResource(R.drawable.tab_out);
[color=#FF0000]flag =1;[/color]//here is need to pause,how to write?
}else {
if(Thread.currentThread() !=null){
Thread.interrupted();
// Thread = null;
}
// thread.
// Thread.interrupted();//pause return boolean
// Thread.sleep(3000);
// Thread.
holder.btns.setBackgroundResource(R.drawable.tab_install);
flag =0;
}
}
});
}
return convertView;
You are trying to interrupt the current thread, You should interrupt the thread you have started. Also are you changing the value of flag. You seem to have multiple variables named flag
if(thread !=null){
thread.interrupt();
}
Related
I have just started exploring google-play-services-turnbased APIs. Till now I have been successful in creating a match. But from the documentation I haven't been able to figure out how to player's score after he completes his turn.
This is my onClickStartMatch method.
public void onStartMatchClicked() {
Intent intent =
Games.TurnBasedMultiplayer.getSelectOpponentsIntent(mHelper.getApiClient(), 1, 7, true);
startActivityForResult(intent, RC_SELECT_PLAYERS);
}
This is my onActivityResult method in my main activity class.
if (request == RC_SELECT_PLAYERS) {
if (response != RESULT_OK) {
// user canceled
return;
}
// Get the invitee list.
final ArrayList<String> invitees =
data.getStringArrayListExtra(Games.EXTRA_PLAYER_IDS);
// Get auto-match criteria.
Bundle autoMatchCriteria = null;
int minAutoMatchPlayers = data.getIntExtra(
Multiplayer.EXTRA_MIN_AUTOMATCH_PLAYERS, 0);
int maxAutoMatchPlayers = data.getIntExtra(
Multiplayer.EXTRA_MAX_AUTOMATCH_PLAYERS, 0);
if (minAutoMatchPlayers > 0) {
autoMatchCriteria = RoomConfig.createAutoMatchCriteria(
minAutoMatchPlayers, maxAutoMatchPlayers, 0);
} else {
autoMatchCriteria = null;
}
TurnBasedMatchConfig tbmc = TurnBasedMatchConfig.builder()
.addInvitedPlayers(invitees)
.setAutoMatchCriteria(autoMatchCriteria)
.build();
// Create and start the match.
Games.TurnBasedMultiplayer
.createMatch(mHelper.getApiClient(), tbmc)
.setResultCallback(new MatchInitiatedCallback());
}
This is my MatchInitiatedCallback class
public class MatchInitiatedCallback implements
ResultCallback<TurnBasedMultiplayer.InitiateMatchResult>,OnTurnBasedMatchUpdateReceivedListener {
#Override
public void onResult(TurnBasedMultiplayer.InitiateMatchResult result) {
// Check if the status code is not success.
Status status = result.getStatus();
if (status.isSuccess()) {
Log.d("turnbased","Turn Based Match Initiated successfully with result: "+status.getStatusMessage());
return;
}
TurnBasedMatch match = result.getMatch();
// If this player is not the first player in this match, continue.
if (match.getData() != null) {
showTurnUI(match);
return;
}
// Otherwise, this is the first player. Initialize the game state.
initGame(match);
// Let the player take the first turn
showTurnUI(match);
}
public void showTurnUI(TurnBasedMatch match){
if(match.getStatus() == TurnBasedMatch.MATCH_STATUS_ACTIVE){
if(match.getTurnStatus() == TurnBasedMatch.MATCH_TURN_STATUS_MY_TURN){
turnBasedMatchData = match.getData();
Games.TurnBasedMultiplayer.takeTurn(mHelper.getApiClient(),match.getMatchId(), "score:400".getBytes(Charset.forName("UTF-16")),null).setResultCallback(updateMatchResult());
}
}
}
public void initGame(TurnBasedMatch match){
Games.TurnBasedMultiplayer.takeTurn(mHelper.getApiClient(),match.getMatchId(),"score:605".getBytes(Charset.forName("UTF-16")),match.getParticipantId(Games.Players.getCurrentPlayerId(mHelper.getApiClient()))).setResultCallback(updateMatchResult());
}
public ResultCallback<TurnBasedMultiplayer.UpdateMatchResult> updateMatchResult(){
return null;
}
#Override
public void onTurnBasedMatchReceived(TurnBasedMatch turnBasedMatch) {
Log.d("turn-based","Player played his turn");
}
#Override
public void onTurnBasedMatchRemoved(String s) {
}
}
}
Also it would helpful if some can properly explain how to continue a game a game from start and when to submit score and how.
Figured it out. This is how you can do it.
public byte[] persist() {
JSONObject retVal = new JSONObject();
try {
retVal.put("turnCounter", 2);
retVal.put("score1",100);
retVal.put("score2",200);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String st = retVal.toString();
Log.d(TAG, "==== PERSISTING\n" + st);
return st.getBytes(Charset.forName("UTF-8"));
}
Games.TurnBasedMultiplayer.takeTurn(mHelper.getApiClient(),match.getMatchId(),persist(),null).setResultCallback(updateMatchResult());
I wrote a custom plugin to read blocks of data from an NfcA(i.e.non-ndef) tag. It seems to work fine , but only after the second scan. I am using Activity intent to derive the "NfcAdapter.EXTRA_TAG" to later use it for reading the values. I am also updating the Intents in onNewIntent(). OnNewIntent gets called after the second scan and after that I get result all the time.But in the first scan onNewIntent does not gets called, hence I end up using the Activity tag that does not have "NfcAdapter.EXTRA_TAG", hence I get null. Please see the my code below.
SE_NfcA.java(my native code for plugin)
#Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
String Result = "";
String TypeOfTalking = "";
if (action.contains("TalkToNFC"))
{
JSONObject arg_object = args.getJSONObject(0);
TypeOfTalking = arg_object.getString("type");
if(TypeOfTalking != "")
{
if (TypeOfTalking.contains("readBlock"))
{
if(TypeOfTalking.contains("#"))
{
try
{
String[] parts = TypeOfTalking.split("#");
int index = Integer.parseInt(parts[1]);
Result = Readblock(cordova.getActivity().getIntent(),(byte)index);
callbackContext.success(Result);
}
catch(Exception e)
{
callbackContext.error("Exception Reading "+ TypeOfTalking + "due to "+ e.toString());
return false;
}
}
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
return true;
}
#Override
public void onNewIntent(Intent intent) {
ShowAlert("onNewIntent called");
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
super.onNewIntent(intent);
getActivity().setIntent(intent);
savedTag = tagFromIntent;
savedIntent = intent;
}
#Override
public void onPause(boolean multitasking) {
Log.d(TAG, "onPause " + getActivity().getIntent());
super.onPause(multitasking);
if (multitasking) {
// nfc can't run in background
stopNfc();
}
}
#Override
public void onResume(boolean multitasking) {
Log.d(TAG, "onResume " + getActivity().getIntent());
super.onResume(multitasking);
startNfc();
}
public String Readblock(Intent Intent,byte block) throws IOException{
byte[] response = new byte[]{};
if(Intent != null)
{
Tag myTag = Intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if(savedTag != null)
myTag = savedTag;
if(myTag != null)
{
try{
Reader nTagReader = new Reader(myTag);
nTagReader.close();
nTagReader.connect();
nTagReader.SectorSelect(Sector.Sector0);
response = nTagReader.fast_read(block, block);
nTagReader.close();
return ConvertH(response);
}catch(Exception e){
ShowAlert(e.toString());
}
}
else
ShowAlert("myTag is null.");
}
return null;
}
private void createPendingIntent() {
if (pendingIntent == null) {
Activity activity = getActivity();
Intent intent = new Intent(activity, activity.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_CLEAR_TOP);
pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0);
}
}
private void startNfc() {
createPendingIntent(); // onResume can call startNfc before execute
getActivity().runOnUiThread(new Runnable() {
public void run() {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
if (nfcAdapter != null && !getActivity().isFinishing()) {
try {
nfcAdapter.enableForegroundDispatch(getActivity(), getPendingIntent(), getIntentFilters(), getTechLists());
if (p2pMessage != null) {
nfcAdapter.setNdefPushMessage(p2pMessage, getActivity());
}
} catch (IllegalStateException e) {
// issue 110 - user exits app with home button while nfc is initializing
Log.w(TAG, "Illegal State Exception starting NFC. Assuming application is terminating.");
}
}
}
});
}
private void stopNfc() {
Log.d(TAG, "stopNfc");
getActivity().runOnUiThread(new Runnable() {
public void run() {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
if (nfcAdapter != null) {
try {
nfcAdapter.disableForegroundDispatch(getActivity());
} catch (IllegalStateException e) {
// issue 125 - user exits app with back button while nfc
Log.w(TAG, "Illegal State Exception stopping NFC. Assuming application is terminating.");
}
}
}
});
}
private Activity getActivity() {
return this.cordova.getActivity();
}
private PendingIntent getPendingIntent() {
return pendingIntent;
}
private IntentFilter[] getIntentFilters() {
return intentFilters.toArray(new IntentFilter[intentFilters.size()]);
}
private String[][] getTechLists() {
//noinspection ToArrayCallWithZeroLengthArrayArgument
return techLists.toArray(new String[0][0]);
}
}
My index.js file
nfc.addTagDiscoveredListener(
function(nfcEvent){
console.log(nfcEvent.tag.id);
alert(nfcEvent.tag.id);
window.echo("readBlock#88");//call to plugin
},
function() {
alert("Listening for NFC tags.");
},
function() {
alert("NFC activation failed.");
}
);
SE_NfcA.js(plugin interface for interaction b/w index.js and SE_NfcA.java)
window.echo = function(natureOfTalk)
{
alert("Inside JS Interface, arg =" + natureOfTalk);
cordova.exec(function(result){alert("Result is : "+result);},
function(error){alert("Some Error happened : "+ error);},
"SE_NfcA","TalkToNFC",[{"type": natureOfTalk}]);
};
I guess I have messed up with the Intents/Activity Life-Cycle, please help. TIA!
I found a tweak/hack and made it to work.
Before making any call to read or write, I made one dummy Initialize call.
window.echo("Initialize");
window.echo("readBlock#88");//call to plugin to read.
And in the native code of the plugin, on receiving the "Initialize" token I made a startNFC() call.
else if(TypeOfTalking.equalsIgnoreCase("Initialize"))
{
startNfc();
}
I released an app on the app store that seems to run into problems with the HTC One. As soon as the app is opened, the app execute an intent to make a phone call, ACTION_CALL. I have a call intent but it's accessed after a button press followed by accessing the location services and then a 5 second sleep() call. But with the HTC Sense, it goes straight to the call, without even showing the layouts. I have a Galaxy S3 running 4.3 and the app's target SDK is 19, and the app is working without a hitch.
Why is this happening? Does the HTC Sense have issues with calling intents? Is there anyway of stopping the intent from occuring, sort of like a signalHandler if it's an HTC Sense device?
HTC Sense 5.0, Android: 4.3
Code (Activity that calls phone intent):
protected void onCreate(Bundle paramBundle) {
super.onCreate(paramBundle);
setContentView(R.layout.activity_test);
x=9;
final TextView localTextView = (TextView) findViewById(R.id.addr);
LocationManager localLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
localLocationManager.getLastKnownLocation("gps");
localLocationManager.requestLocationUpdates("gps", 2000L, 10.0F, new LocationListener() {
public void onLocationChanged(Location paramAnonymousLocation) {
double d1 = paramAnonymousLocation.getLatitude();
double d2 = paramAnonymousLocation.getLongitude();
Geocoder localGeocoder = new Geocoder(Test.this.getApplicationContext(), Locale.getDefault());
try {
List localList = localGeocoder.getFromLocation(d1, d2, 1);
if (localList.size() == 1) {
Address localAddress = (Address) localList.get(0);
Object[] arrayOfObject = new Object[3];
if (localAddress.getMaxAddressLineIndex() > 0) ;
for (String str1 = localAddress.getAddressLine(0); ; str1 = "") {
arrayOfObject[0] = str1;
arrayOfObject[1] = localAddress.getAddressLine(1);
arrayOfObject[2] = localAddress.getCountryName();
String str2 = String.format("%s, %s, %s", arrayOfObject);
localTextView.setText(str2);
if(x==9){
Test.this.waititout();}
return;
}
}
} catch (IOException localIOException) {
localIOException.printStackTrace();
return;
} catch (InterruptedException localInterruptedException) {
localInterruptedException.printStackTrace();
}
}
public void onProviderDisabled(String paramAnonymousString) {
localTextView.setText("TURN ON GPS DUMMY");
}
public void onProviderEnabled(String paramAnonymousString) {
}
public void onStatusChanged(String paramAnonymousString, int paramAnonymousInt, Bundle paramAnonymousBundle) {
}
});
}
public void waititout()
throws InterruptedException {
new Thread() {
public void run() {
try {
Date localDate = new Date();
Calendar localCalendar = GregorianCalendar.getInstance();
localCalendar.setTime(localDate);
int i = localCalendar.get(Calendar.HOUR_OF_DAY);
Thread.currentThread();
Thread.sleep(4000L);
Intent localIntent = new Intent("android.intent.action.CALL");
localIntent.setData(Uri.parse("tel:17325450900"));
Test.this.startActivity(localIntent);
return;
} catch (InterruptedException localInterruptedException) {
System.out.println(localInterruptedException);
}
}
}
.start();
}
Hi i am blinking the flashlight on incoming call and i am able to do that using this code but the problem is the flashlight is not getting stopped when the call is attended or cut
I am trying to stop the service from every way but the flashlight doesnot stops untill the loop is completed
In receiver class...
Intent in = new Intent(context, Run.class);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
in.putExtra("state", state);
context.startService(in);
} else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
// Toast.makeText(context, "Idle", Toast.LENGTH_LONG).show();
context.stopService(in);
} else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
// Toast.makeText(context, "Offhook", Toast.LENGTH_LONG).show();
context.stopService(in);
}
In Service class...
Camera cam;
Parameters p;
String state;
String tag="Runserve";
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
try {
cam = Camera.open();
p = cam.getParameters();
String myString = "0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011";
long blinkDelay = 50;
for (int i = 0; i < myString.length(); i++) {
state=intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
break;
}else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
break;
}
if (myString.charAt(i) == '0') {
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
cam.setParameters(p);
} else {
p.setFlashMode(Parameters.FLASH_MODE_OFF);
cam.setParameters(p);
}
Thread.sleep(blinkDelay);
}
}catch (Exception e) {
// TODO: handle exception
Log.d(tag, "in catch1");
Log.d(tag, e.toString());
}
}else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
try {
p.setFlashMode(Parameters.FLASH_MODE_OFF);
cam.release();
} catch (Exception e) {
// TODO: handle exception
Log.d(tag, e.toString());
}
stopSelf();
}else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
try {
p.setFlashMode(Parameters.FLASH_MODE_OFF);
cam.release();
} catch (Exception e) {
// TODO: handle exception
Log.d(tag, e.toString());
}
stopSelf();
}
}
I am making the app in which i can attend the call through proximity sensor.This code has 2 intents First is i i.e working for versions less than Android 4.0 and another is headSetUnPluggedintent i.e working on Android 4.1. Is there any single way through which calls can be attended by all versions
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
TelephonyManager mgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
int callState = mgr.getCallState();
if(callState==TelephonyManager.CALL_STATE_RINGING) {
callState = mgr.getCallState();
String x="0.0";
String y=(String.valueOf(event.values[0]));
if( x.equals(y)){
//Toast.makeText(getApplicationContext(), "Proxy", Toast.LENGTH_SHORT).show();
try{
Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
i.putExtra(Intent.EXTRA_KEY_EVENT,new KeyEvent(KeyEvent.ACTION_UP,KeyEvent.KEYCODE_HEADSETHOOK));
sendOrderedBroadcast(i, "android.permission.CALL_PRIVILEGED");
Intent headSetUnPluggedintent = new Intent(Intent.ACTION_HEADSET_PLUG);
headSetUnPluggedintent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
headSetUnPluggedintent.putExtra("state", 0);
headSetUnPluggedintent.putExtra("name", "Headset");
sendOrderedBroadcast(headSetUnPluggedintent, null);
if(callState==TelephonyManager.CALL_STATE_OFFHOOK){
headSetUnPluggedintent=null;
i=null;
}else if(callState==TelephonyManager.CALL_STATE_IDLE){
headSetUnPluggedintent=null;
i=null;
}
}catch(Exception e){
Log.d(tag, e.toString());
}
}
Several points here :
in the for loop, it's useless to check the value of state as you have already checked it in your if condition. state is a String (i.e.immutable), it's value is not going to change.
you need to get, for each iteration, the current state of the call, using TelephonyManager#getCallState(). Something like this (not tested) :
TelephonyManager mgr = getSystemService(Context.TELEPHONY_SERVICE);
int callState = mgr.getCallState();
if (callState != TelephonyManager.CALL_STATE_RINGING )
break;
You should normally not attempt to stop a IntentService, it stops itself when all work is done (that is when onHandleIntent returns).
Also, the IntentService javadoc states that you should not call stopSelf().
I have a problem on android. I have an application that asks the user for the local Ip address (from the device's interface) and another remote address. The application has to bind to the specified local address and connect to the remote address. Quite simple, but, indeed, bind does not work ass i expected..
I added the following permissions on the manifest file:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
The source code is the following one:
public class MainActivity extends Activity
{
String Tag = "TAG";
private int LOCAL_PORT = 4444;
private int REMOTE_PORT = 80;
private EditText LOCAL;
private EditText REMOTE;
private Button Connect;
private TextView STATUS;
private Context context = this;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LOCAL = (EditText) findViewById(R.id.editText1);
REMOTE = (EditText) findViewById(R.id.editText2);
Connect = (Button) findViewById(R.id.button1);
Connect.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
BotleneckHandle WORK;
Toast.makeText(getApplicationContext(), "Proceeding to connect",
Toast.LENGTH_SHORT).show();
/*
if(LOCAL.getText().toString() == null || REMOTE.getText().toString() == null || LOCAL.getText().toString().equals(" ") || REMOTE.getText().toString().equals(" ") || LOCAL.getText().toString().equals("") || REMOTE.getText().toString().equals(""))
Toast.makeText(context, "Wrong parameters", 2000);
else
{
Toast.makeText(getApplicationContext(), "Proceeding to connect",Toast.LENGTH_SHORT).show();
}*/
WORK = new BotleneckHandle();
WORK.execute();
}
});
STATUS = (TextView) findViewById(R.id.textView1);
}
private class BotleneckHandle extends AsyncTask <Void , Void , String>
{
Socket Skt = null;
String ReturnStatemente = new String();
SocketAddress localAddr = new InetSocketAddress(LOCAL.getText().toString(), LOCAL_PORT);
protected void onPreExecute(){ }
protected String doInBackground(Void... params)
{
try
{
String s=new String();
s+= "Local="+LOCAL.getText().toString()+":"+LOCAL_PORT+" Remote="+REMOTE.getText().toString()+":"+REMOTE_PORT; //so far so good, Confirmed by debug
Toast.makeText(getApplicationContext(), s,Toast.LENGTH_SHORT).show(); //Does not show anything due the fact that i didn't published it as an assync task update..
//binding to a local address
Skt.bind(localAddr); //cannot make the bind :-/
//connecting to remote host
Skt=new Socket(REMOTE.getText().toString(), REMOTE_PORT); //if bind is comment, still does not work.. I bet
ReturnStatemente = "Connected";
}
catch (UnknownHostException e)
{
e.printStackTrace();
Toast.makeText(context, "Unknown remote host", 2000);
ReturnStatemente = "Not Connected";
}
catch (IOException e)
{
e.printStackTrace();
Toast.makeText(context, "Connection fail", 2000);
ReturnStatemente = "Not Connected";
}
finally{try {
Skt.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}
return ReturnStatemente;
}
protected void onPostExecute(String result) { STATUS.setText(" CONECTION STATUS == " + result); }
}
}
What am i doing wrong on bind? As far as i see, and as i searched for its good.. Did i miss something?
kind regards
You're trying to call bind on a variable before you assigned anything to it. So its still null. That isn't going to work. You need to create an instance of Socket before you can call methods on it.