(REQ) How to Add Kill Long Press Kill Apps+ Long press volume keys to skip tracks - Sony Ericsson Xperia Mini, Mini Pro, Xperia Pro, A

Does anyone know which jar files and smali files/codes( lines) for adding music control and long press back button to kill apps ?
I need name of files and smali codes.

I need it, too

i think its android-policy.jar or services.jar maybe.

i need it too

AW: (REQ) How to Add Kill Long Press Kill Apps+ Long press volume keys to skip tracks
me too

This is what would be added for Settings:
packages/apps/Settings/src/com/android/settings/DevelopmentSettings.java
Code:
packages/apps/Settings/src/com/android/settings/DevelopmentSettings.java
public class DevelopmentSettings extends PreferenceActivity
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
private static final String KILL_APP_LONGPRESS_BACK = "kill_app_longpress_back";
private CheckBoxPreference mKillAppLongpressBack;
addPreferencesFromResource(R.xml.development_prefs);
mKillAppLongpressBack = (CheckBoxPreference) findPreference(KILL_APP_LONGPRESS_BACK);
}
@Override
protected void onResume() {
super.onResume();
mKillAppLongpressBack.setChecked(Settings.Secure.getInt(getContentResolver(),
Settings.Secure.KILL_APP_LONGPRESS_BACK, 0) != 0);
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
} else if (preference == mKillAppLongpressBack) {
Settings.Secure.putInt(getContentResolver(), Settings.Secure.KILL_APP_LONGPRESS_BACK,
mKillAppLongpressBack.isChecked() ? 1 : 0);
}
And for frameworks:
policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
Code:
Runnable mBackLongPress = new Runnable() {
public void run() {
if (Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.KILL_APP_LONGPRESS_BACK, 0) == 0) {
return;
}
try {
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
IActivityManager mgr = ActivityManagerNative.getDefault();
List<RunningAppProcessInfo> apps = mgr.getRunningAppProcesses();
for (RunningAppProcessInfo appInfo : apps) {
int uid = appInfo.uid;
// Make sure it's a foreground USER application
if (uid >= Process.FIRST_APPLICATION_UID && uid <= Process.LAST_APPLICATION_UID
&& appInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
// Kill the entire pid
Toast.makeText(mContext, com.android.internal.R.string.app_killed_message, Toast.LENGTH_SHORT).show();
Process.killProcess(appInfo.pid);
break;
}
}
I SAW IT FROM SAMSUNG PHONE, NOT SURE ABOUT OUR SONY
TELL ME IF IT WORKS

TeamIndia said:
This is what would be added for Settings:
packages/apps/Settings/src/com/android/settings/DevelopmentSettings.java
Code:
packages/apps/Settings/src/com/android/settings/DevelopmentSettings.java
public class DevelopmentSettings extends PreferenceActivity
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
private static final String KILL_APP_LONGPRESS_BACK = "kill_app_longpress_back";
private CheckBoxPreference mKillAppLongpressBack;
addPreferencesFromResource(R.xml.development_prefs);
mKillAppLongpressBack = (CheckBoxPreference) findPreference(KILL_APP_LONGPRESS_BACK);
}
@Override
protected void onResume() {
super.onResume();
mKillAppLongpressBack.setChecked(Settings.Secure.getInt(getContentResolver(),
Settings.Secure.KILL_APP_LONGPRESS_BACK, 0) != 0);
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
} else if (preference == mKillAppLongpressBack) {
Settings.Secure.putInt(getContentResolver(), Settings.Secure.KILL_APP_LONGPRESS_BACK,
mKillAppLongpressBack.isChecked() ? 1 : 0);
}
And for frameworks:
policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
Code:
Runnable mBackLongPress = new Runnable() {
public void run() {
if (Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.KILL_APP_LONGPRESS_BACK, 0) == 0) {
return;
}
try {
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
IActivityManager mgr = ActivityManagerNative.getDefault();
List<RunningAppProcessInfo> apps = mgr.getRunningAppProcesses();
for (RunningAppProcessInfo appInfo : apps) {
int uid = appInfo.uid;
// Make sure it's a foreground USER application
if (uid >= Process.FIRST_APPLICATION_UID && uid <= Process.LAST_APPLICATION_UID
&& appInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
// Kill the entire pid
Toast.makeText(mContext, com.android.internal.R.string.app_killed_message, Toast.LENGTH_SHORT).show();
Process.killProcess(appInfo.pid);
break;
}
}
I SAW IT FROM SAMSUNG PHONE, NOT SURE ABOUT OUR SONY
TELL ME IF IT WORKS
Click to expand...
Click to collapse
no its completely different...bcz we dont u use kill concept smali...
so we have to mod android.policy.jar
settings.apk
and fw-res.apk..
iam almost making a tut for it...will add it in my tut thread soon..

Related

[Q] Refer to TTS Object inside inner method.

Well... I am trying to create an application using the TTS Engine.
I can already make it, work, no problem. However I need my buttons to be dinamic, they will come from a database.
**So far you guys have helped me a lot, since now I can do it thanks to the tips I got from you guys.**
**Well.. now I am stuck again.**
Every new button that I create I attach an OnClickListener so it can start the TTS and speak something.
However it's an inner method, so, when I try to run the code below, it gives me a NullPointerException when it tries to "speak" using the TTS. I know the TTS object is out of context, so, **How can I solve this?**
Below the code. It's a little big since I wanted to include everything:
PLEASE JUMP TO THE "HERE IS MY PROBLEM!!!" comment so you guys can see exactly where my problem is. I know where it is, but I don't know how to solve it =(
Any help is appreciatted! =)
Code:
public class LivoxTesteActivity extends Activity implements OnInitListener{
/** Called when the activity is first created. */
private int MY_DATA_CHECK_CODE = 0;
public TextToSpeech tts;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
LinearLayout lgeral = new LinearLayout (this);
lgeral.setOrientation(LinearLayout.VERTICAL);
lgeral.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, 1f));
String array[][] = {{"Comer","eat", "Eu quero comer", "1"},
{"Abraço","hug", "Eu quero um abraço", "2"},
{"Assustado","afraid", "Eu estou com medo", "3"},
{"Beber","drink", "Eu quero beber", "4"}};
int x = array.length;
int qtdeLinhas = 2;
for (int j = 0; j < qtdeLinhas; j++) {
LinearLayout l1 = new LinearLayout (this);
l1.setOrientation(LinearLayout.HORIZONTAL);
l1.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, 1f));
FrameLayout fl;
for (int i = 0; i < array.length; i++) {
fl = (FrameLayout)LayoutInflater.from(getBaseContext()).inflate(R.layout.framelayoutstyle, l1, false);
TextView textoEscrito;
textoEscrito = (TextView)LayoutInflater.from(getBaseContext()).inflate(R.layout.textviewstyle, fl, false);
textoEscrito.setText(array[i][0]);
final String texto = textoEscrito.getText().toString();
final String textoFalar = array[i][2];
ImageButton btn;
btn = (ImageButton)LayoutInflater.from(getBaseContext()).inflate(R.layout.imagebuttonstyle, fl, false);
btn.setImageResource(this.getResources().getIdentifier("drawable/" + array[i][1], null, this.getPackageName()));
btn.setOnClickListener(new Button.OnClickListener(){
public void onClick (View v){
Toast.makeText(getBaseContext(), texto, Toast.LENGTH_SHORT).show();
//*******************************
//HERE IS MY PROBLEM!!!
//*******************************
tts.speak(txtFl, TextToSpeech.QUEUE_ADD, null);
//*******************************
//WHEN I TRY TO RUN THE ABOVE IT GIVES A NULLPOINTEREXCEPTION!!!
//*******************************
}
});
fl.addView(btn);
fl.addView(textoEscrito);
l1.addView(fl);
}
lgeral.addView(l1);
}
setContentView(lgeral);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
// success, create the TTS instance
tts = new TextToSpeech(this, this);
}
else {
// missing data, install it
Intent installIntent = new Intent();
installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
}
}
}
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
}
else if (status == TextToSpeech.ERROR) {
}
}
@Override
public void onDestroy() {
if (tts != null) {
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
}
By the way... the method Toast.makeText(getBaseContext(), texto, Toast.LENGTH_SHORT).show(); works fine. I believe that's because the Toast is a static class.
So, maybe the solution is to create a static class with the method to speak? Ideas? How can I do it?
Questions or Problems Should Not Be Posted in the Development Forum
Please Post in the Correct Forums
Moving to Q&A

[Q] Get Android build number in app

Hi there,
I am writing an app and for one of the features I need the firmware build number.
I know I can get the firmware version(like 4.1.1) with android.os.build but I need the build number of a rom(like "Rom version 1.0") thats stored in build.prop. I know I can parse the whole build.prop file and extract the 1 string of information but is there another way to get is faster and that it doesnt require root to use?
Grtz,
Thirith
Solved it
I solved my own question
Here is how I did it(in case somebody wants to achieve the same thing):
Code:
TextView tv = (TextView)findViewById(R.id.text1);
String input = "getprop |awk -F : '/build.display.id/ { print $2 }'";
execCommandLine(input, tv);
void execCommandLine(String command, TextView tv)
{
Runtime runtime = Runtime.getRuntime();
Process proc = null;
OutputStreamWriter osw = null;
// Running the Script
try
{
proc = runtime.exec("su");
osw = new OutputStreamWriter(proc.getOutputStream());
osw.write(command);
osw.flush();
osw.close();
}
// If return error
catch (IOException ex)
{
// Log error
Log.e("execCommandLine()", "Command resulted in an IO Exception: " + command);
return;
}
// Try to close the process
finally
{
if (osw != null)
{
try
{
osw.close();
}
catch (IOException e){}
}
}
try
{
proc.waitFor();
}
catch (InterruptedException e){}
// Display on screen if error
if (proc.exitValue() != 0)
{
Log.e("execCommandLine()", "Command returned error: " + command + "\n Exit code: " + proc.exitValue());
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage(command + "\nWas not executed sucessfully!");
builder.setNeutralButton("OK", null);
AlertDialog dialog = builder.create();
dialog.setTitle("Script Error");
dialog.show();
}
BufferedReader reader = new BufferedReader(
new InputStreamReader(proc.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
try {
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String exit = output.toString();
if(exit != null && exit.length() == 0) {
exit = "Command executed Successfully but no output was generated";
}
tv.setText(exit);
}
Hi, thanks for making your code public!
Just got an error when trying your code into my app.
Line
Code:
execCommandLine(input, tv);
runs into this error:
Multiple markers at this line
- input cannot be resolved to a type
- Return type for the method is missing
- Syntax error on token ",", delete this
token
Click to expand...
Click to collapse
How do I fix it?
Ok, did a mistake with integrating the code. My whole activity:
Code:
package de.yanniks.cm_updatechecker;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import de.yanniks.cm_updatechecker.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class UpdateChecker extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.updatecheck);
TextView tv = (TextView)findViewById(R.id.installedversion);
String input = "getprop |awk -F : '/build.display.id/ { print $2 }'";
execCommandLine(input, tv);}
void execCommandLine(String command, TextView tv)
{
Runtime runtime = Runtime.getRuntime();
Process proc = null;
OutputStreamWriter osw = null;
// Running the Script
try
{
proc = runtime.exec("su");
osw = new OutputStreamWriter(proc.getOutputStream());
osw.write(command);
osw.flush();
osw.close();
}
// If return error
catch (IOException ex)
{
// Log error
Log.e("execCommandLine()", "Command resulted in an IO Exception: " + command);
return;
}
// Try to close the process
finally
{
if (osw != null)
{
try
{
osw.close();
}
catch (IOException e){}
}
}
try
{
proc.waitFor();
}
catch (InterruptedException e){}
// Display on screen if error
if (proc.exitValue() != 0)
{
Log.e("execCommandLine()", "Command returned error: " + command + "\n Exit code: " + proc.exitValue());
AlertDialog.Builder builder = new AlertDialog.Builder(UpdateChecker.this);
builder.setMessage(command + "\nWas not executed sucessfully!");
builder.setNeutralButton("OK", null);
AlertDialog dialog = builder.create();
dialog.setTitle("Script Error");
dialog.show();
}
BufferedReader reader = new BufferedReader(
new InputStreamReader(proc.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
try {
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String exit = output.toString();
if(exit != null && exit.length() == 0) {
exit = "Command executed Successfully but no output was generated";
}
tv.setText(exit);
}
}
A better solution is to use my SystemProperties.get("build.display.id") directly instead of forking a native binary.
Code:
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.ByteOrder;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class SystemProperties {
public static final int PROP_NAME_MAX= 32; // sic
public static final int PROP_VALUE_MAX= 92; // sic
public static final int PROP_AREA_MAGIC= 0x504f5250; // "PROP"
public static final int PROP_AREA_VERSION= 0x45434f76; // "vOCE" (API level 3..8 at least)
public static final String PROP_SERVICE_NAME= "property_service";
public static final String WORKSPACE= "ANDROID_PROPERTY_WORKSPACE";
// prop_area struct
public static final int PA_COUNT= 0;
public static final int PA_SERIAL= 4;
public static final int PA_MAGIC= 8;
public static final int PA_VERSION= 12;
public static final int PA_RESERVED= 16;
public static final int PA_TOC= 32;
public static final int PA_INFO_NAME= 0;
public static final int PA_INFO_SERIAL= PA_INFO_NAME+PROP_NAME_MAX;
public static final int PA_INFO_VALUE= PA_INFO_SERIAL+4;
private static MappedByteBuffer mMap= null;
private static boolean init() throws IllegalArgumentException,
SecurityException,
NoSuchFieldException,
IllegalAccessException,
IOException {
FileDescriptor fd;
MappedByteBuffer mbb= null;
String workspace= System.getenv(WORKSPACE);
if (workspace == null) {
throw new IllegalArgumentException(WORKSPACE + " not set");
}
String[] wsArray= workspace.split(",");
int osFd= 0;
int len= 0;
try {
osFd= new Integer(wsArray[0]);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(e.getMessage());
}
try {
len= new Integer(wsArray[1]);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(e.getMessage());
}
//Log.i(TAG, "Read fd " + Integer.toString(osFd) + " for " + len + " bytes.");
fd= new FileDescriptor();
Class<?> c= fd.getClass();
Field f= c.getDeclaredField("descriptor");
f.setAccessible(true);
f.setInt(fd, osFd);
FileInputStream in= new FileInputStream(fd);
FileChannel fc= in.getChannel();
mbb= fc.map(FileChannel.MapMode.READ_ONLY, 0, len);
mbb.order(ByteOrder.LITTLE_ENDIAN);
if (mbb.getInt(PA_MAGIC) != PROP_AREA_MAGIC) {
throw new IllegalArgumentException("Wrong kind of magic " + Integer.toString(mbb.getInt(PA_MAGIC), 16));
}
if (mbb.getInt(PA_VERSION) != PROP_AREA_VERSION) {
throw new IllegalArgumentException("Incorrect version " + Integer.toString(mbb.getInt(PA_VERSION), 16));
}
mMap= mbb;
return(true);
}
public static String get(String key) throws IllegalArgumentException,
SecurityException,
NoSuchFieldException,
IllegalAccessException,
IOException {
if (mMap == null) {
if (!init())
return(null);
}
int index= property_find(key);
//Log.i(TAG, "Found entry at " + Integer.toString(index));
if (index < 0)
return(null);
return(getString(index+PA_INFO_VALUE));
}
private static int property_find(String name) {
int count= mMap.getInt(PA_COUNT);
int tok= -1;
//Log.i(TAG, "Key " + name);
next: while(count-- > 0) {
tok++;
int entry= mMap.getInt(PA_TOC + tok*4);
//Log.i(TAG, "Entry " + tok + ": " + Integer.toString(entry, 16));
if ((entry >> 24) != name.length())
continue;
int index= (entry & 0xFFFFFF);
//Log.i(TAG, "Index " + index);
for (int i=0; i<name.length(); i++) {
//Log.i(TAG, "Cmp(" + entry + ":" + index + ":" + i + "): " + (char)(mbb.get(index+i)) + " -- " + name.charAt(i));
if ((char)(mMap.get(index+i)) != name.charAt(i)) {
continue next;
}
}
// found
return(index);
}
return(-1);
}
private static String getString(int index) {
byte b[]= new byte[PROP_VALUE_MAX];
int i= 0;
do {
b[i]= mMap.get(i+index);
} while (b[i++] != 0);
return(new String(b, 0, i-1));
}
}
Sorry 'bout the terrible indentation. Cut'n'paste isn't my code's best friend, obviously.

Help for Avin App or Auxiliary in

I have a problem that my monkeyboard Dab receiver needs audio in. This can be switched with the avin app. But I only need the Audio switched not the video. Is it possible to make a Task with Tasker or similar to run some code or script to switch the audio.
Because also after boot the avin app is blocking the system. For example pppwidget starts only after exiting the avin app.
I also did take a look at the code of the app but I am a completely noob at java app programming and could not identify the code for switching the audio.
Can anyone understand and help me please?
Thanks
I am on malaysk kitkat rom.
here is the code i could decompile. Maybe it is useful for my Problem
MTCAVIN.apk com microntek avin AVINActivity.java
package com.microntek.avin;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings.System;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager.LayoutParams;
import android.widget.ImageView;
public class AVINActivity extends Activity {
private static boolean activityVisible;
private static boolean statusbarshow;
private static boolean videoEnable;
private BroadcastReceiver AVINBootReceiver;
private final int MSG_CAPTURE_OFF;
private final int MSG_CAPTURE_ON;
private final int MSG_TIME_TICK;
private final int MSG_VIDEO_CHECK;
private AudioManager am;
private Handler mHandler;
private ImageView mImageBlack;
private ImageView mImageScreen;
private boolean mInChannel;
private boolean mIsSignal;
private View mTextWarning;
private View signalshow;
private int startbackflag;
private int statusbarhidetime;
/* renamed from: com.microntek.avin.AVINActivity.1 */
class C00001 extends Handler {
C00001() {
}
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 65281:
AVINActivity.this.captureOn();
case 65282:
AVINActivity.this.captureOff();
case 65283:
AVINActivity.this.videoCheck();
case 65284:
AVINActivity.this.refresTick();
AVINActivity.this.mHandler.sendEmptyMessageDelayed(65284, 1000);
default:
}
}
}
/* renamed from: com.microntek.avin.AVINActivity.2 */
class C00012 implements OnClickListener {
C00012() {
}
public void onClick(View v) {
if (!AVINActivity.statusbarshow) {
AVINActivity.statusbarshow = true;
AVINActivity.this.mHandler.removeMessages(65284);
AVINActivity.this.mHandler.sendEmptyMessageDelayed(65284, 1000);
AVINActivity.this.statusbarhidetime = 0;
AVINActivity.this.resumeStatusBar();
} else if (AVINActivity.this.mIsSignal && AVINActivity.videoEnable) {
AVINActivity.statusbarshow = false;
AVINActivity.this.hideStatusBar();
}
}
}
/* renamed from: com.microntek.avin.AVINActivity.3 */
class C00023 extends BroadcastReceiver {
C00023() {
}
public void onReceive(Context arg0, Intent arg1) {
String action = arg1.getAction();
if (action.equals("com.microntek.bootcheck")) {
String classname = arg1.getStringExtra("class");
if (!classname.equals("com.microntek.avin") && !classname.equals("phonecallin") && !classname.equals("phonecallout")) {
AVINActivity.this.sendFinish();
}
} else if (action.equals("com.microntek.carstatechange")) {
if (AVINActivity.activityVisible && arg1.getStringExtra("type").equals("SAFE")) {
AVINActivity.videoEnable = AVINActivity.this.GetDrivingVideoEnable();
AVINActivity.this.mHandler.removeMessages(65283);
AVINActivity.this.mHandler.sendEmptyMessageDelayed(65283, 100);
}
} else if (action.equals("com.microntek.videosignalchange") && arg1.getStringExtra("type").equals("avin")) {
AVINActivity.this.mIsSignal = arg1.getBooleanExtra("sta", true);
AVINActivity.videoEnable = AVINActivity.this.GetDrivingVideoEnable();
AVINActivity.this.mHandler.removeMessages(65283);
AVINActivity.this.mHandler.sendEmptyMessageDelayed(65283, 100);
}
}
}
public AVINActivity() {
this.MSG_CAPTURE_ON = 65281;
this.MSG_CAPTURE_OFF = 65282;
this.MSG_VIDEO_CHECK = 65283;
this.MSG_TIME_TICK = 65284;
this.mImageBlack = null;
this.mTextWarning = null;
this.signalshow = null;
this.mImageScreen = null;
this.mIsSignal = true;
this.startbackflag = 0;
this.statusbarhidetime = 0;
this.am = null;
this.mInChannel = false;
this.mHandler = new C00001();
this.AVINBootReceiver = new C00023();
}
static {
videoEnable = false;
activityVisible = false;
statusbarshow = true;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.startbackflag = getIntent().getIntExtra("start", 0);
if (this.startbackflag != 0) {
moveTaskToBack(true);
}
Intent it1 = new Intent("com.microntek.bootcheck");
it1.putExtra("class", "com.microntek.avin");
sendBroadcast(it1);
this.am = (AudioManager) getSystemService("audio");
this.statusbarhidetime = 0;
setContentView(R.layout.main);
this.signalshow = findViewById(R.id.signalshow);
this.mImageScreen = (ImageView) findViewById(R.id.screen);
this.mImageScreen.setOnClickListener(new C00012());
this.mImageBlack = (ImageView) findViewById(R.id.black);
this.mTextWarning = findViewById(R.id.safewarning);
IntentFilter itfl = new IntentFilter();
itfl.addAction("com.microntek.bootcheck");
itfl.addAction("com.microntek.carstatechange");
itfl.addAction("com.microntek.videosignalchange");
registerReceiver(this.AVINBootReceiver, itfl);
deviceOn();
sendCanBusAvinOn();
this.mHandler.sendEmptyMessageDelayed(65284, 1000);
}
private void sendFinish() {
deviceOff();
finish();
}
private void deviceOn() {
if (!this.mInChannel) {
this.am.setParameters("av_channel_enter=line");
this.mInChannel = true;
}
}
private void deviceOff() {
if (this.mInChannel) {
this.mInChannel = false;
this.am.setParameters("av_channel_exit=line");
}
}
private void sendCanBusAvinOn() {
Intent it1 = new Intent("com.microntek.canbusdisplay");
it1.putExtra("type", "avin-on");
sendBroadcast(it1);
}
private void sendCanBusAvinOff() {
Intent it1 = new Intent("com.microntek.canbusdisplay");
it1.putExtra("type", "avin-off");
sendBroadcast(it1);
}
public void onBackPressed() {
sendFinish();
}
private void refresTick() {
if (!this.mIsSignal) {
boolean en = GetDrivingVideoEnable();
if (videoEnable != en) {
videoEnable = en;
this.mHandler.removeMessages(65283);
this.mHandler.sendEmptyMessageDelayed(65283, 100);
}
}
if (this.statusbarhidetime < 10) {
this.statusbarhidetime++;
if (this.statusbarhidetime == 10 && videoEnable && statusbarshow) {
statusbarshow = false;
hideStatusBar();
}
}
}
private boolean GetDrivingVideoEnable() {
if (System.getInt(getContentResolver(), "DrivingVideoEN", 0) != 0) {
return true;
}
if (this.am.getParameters("sta_driving=").equals("true")) {
return false;
}
return true;
}
public void hideStatusBar() {
if (this.mIsSignal) {
Window win = getWindow();
LayoutParams winParams = win.getAttributes();
winParams.flags |= 1024;
win.setAttributes(winParams);
}
}
public void resumeStatusBar() {
Window win = getWindow();
LayoutParams winParams = win.getAttributes();
winParams.flags &= -1025;
win.setAttributes(winParams);
}
protected void onResume() {
super.onResume();
statusbarshow = true;
activityVisible = true;
resumeStatusBar();
captureOn();
videoEnable = GetDrivingVideoEnable();
this.mHandler.sendEmptyMessageDelayed(65283, 100);
sendBroadcast(new Intent("com.microntek.musicclockreset"));
}
protected void onPause() {
activityVisible = false;
captureOff();
super.onPause();
}
protected void onDestroy() {
this.mHandler.removeCallbacksAndMessages(null);
unregisterReceiver(this.AVINBootReceiver);
deviceOff();
sendCanBusAvinOff();
super.onDestroy();
}
protected void videoCheck() {
if (videoEnable) {
this.mTextWarning.setVisibility(4);
} else {
this.mTextWarning.setVisibility(0);
}
if (this.mIsSignal) {
this.signalshow.setVisibility(8);
return;
}
this.signalshow.setVisibility(0);
this.statusbarhidetime = 0;
if (!statusbarshow) {
resumeStatusBar();
}
statusbarshow = true;
}
protected void captureOn() {
this.am.setParameters("ctl_capture_on=line");
this.mImageBlack.setVisibility(4);
}
protected void captureOff() {
this.mImageBlack.setVisibility(0);
this.am.setParameters("ctl_capture_off=line");
}
}
Privacy Policy
Maybe simple shell command or something? Anyone?
I did a simple Tweak in the Avin app. Now it launches without Ui. For audio in only and only for kitkat roms.
I have a typo in the attached APK...
Hey there, sorry to disturb the old thread I need avin.apk only to show video input, and not cut audio in background for Spotify. Do you think I have a chance?
I suppose It is the direct oppossite of yours.
ivellios said:
Hey there, sorry to disturb the old thread I need avin.apk only to show video input, and not cut audio in background for Spotify. Do you think I have a chance?
I suppose It is the direct oppossite of yours.
Click to expand...
Click to collapse
2nd - if you're still around - can you recompile with this ?
Might be as simple as commenting out the this.am.setParameters calls
Sorry, this is not possible for me. I did not figure it out how to disable the video.

System App reverse enginnering

Hello there!
I would need some help reverse engineering an app and recompiling it with some different code afterwards.
The App coordinates all the different components of my phone to work properly.
When you press the two fingerprint sensors, the app gives you haptic feedback and turns the screen from front to back or vice versa, depending on which side is facing up.
I need the app to do exactly that once when i wake up my phone either with fingerprint or power button, so the display illuminates which is facing up, and not the one i used recently.
I have some experience with java, but all i got are the .smali documents.
Is there any way to reliably get smali into java and back?
Code:
Code:
package org.mokee.settings.keyhandler;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
import android.os.Vibrator;
import android.provider.Settings.Secure;
import android.provider.Settings.System;
import android.telephony.TelephonyManager;
import android.view.KeyEvent;
import com.android.internal.os.DeviceKeyHandler;
import org.mokee.internal.util.FileUtils;
import org.mokee.internal.util.PowerMenuConstants;
import org.mokee.settings.detector.MotionDetector;
import org.mokee.settings.detector.MotionDetector.MotionListener;
import org.mokee.settings.dualscreen.ScreenHelper;
public class KeyHandler implements DeviceKeyHandler {
private static final long DEBOUNCE_DELAY_MILLIS = 150;
public static final String FINGER_SWITCH_SETTING_KEY = "finger_switch_switch";
public static final String FORCE_FRONT_ON_CALL = "force_front_on_call";
public static final int FP_LEFT_KEY = 133;
public static final int FP_RIGHT_KEY = 134;
private static final int SWITCH_WAKELOCK_DURATION = 3000;
public static final String WAKE_FRONT_ON_CALL = "wake_front_on_call";
/* access modifiers changed from: private */
public static boolean sForceFrontOnRinging = true;
/* access modifiers changed from: private */
public static boolean sInCallRinging = false;
/* access modifiers changed from: private */
public static boolean sPressSwitch = true;
/* access modifiers changed from: private */
public static boolean sScreenTurnedOn = true;
/* access modifiers changed from: private */
public static boolean sWakeFrontOnRinging = true;
private KeyguardManager keyguardManager;
/* access modifiers changed from: private */
public final Context mContext;
private long mLeftFpDownTime = 0;
private boolean mLeftKeyPressed = false;
/* access modifiers changed from: private */
public MotionDetector mMotionDetector;
private final PowerManager mPowerManager;
private long mRightFpDownTime = 0;
private boolean mRightKeyPressed = false;
private final BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.SCREEN_OFF")) {
KeyHandler.sScreenTurnedOn = false;
} else if (intent.getAction().equals("android.intent.action.SCREEN_ON")) {
KeyHandler.sScreenTurnedOn = true;
if (KeyHandler.sInCallRinging && KeyHandler.sWakeFrontOnRinging) {
KeyHandler.this.mSwitchScreenHandler.post(new SwitchRunnable(1));
}
} else if (intent.getAction().equals("android.intent.action.PHONE_STATE")) {
if (KeyHandler.this.mTelephonyManager == null) {
KeyHandler.this.mTelephonyManager = (TelephonyManager) KeyHandler.this.mContext.getSystemService("phone");
}
if (KeyHandler.this.mTelephonyManager.getCallState() == 1) {
KeyHandler.sInCallRinging = true;
if (KeyHandler.sScreenTurnedOn && KeyHandler.sForceFrontOnRinging) {
KeyHandler.this.mSwitchScreenHandler.post(new SwitchRunnable(1));
return;
}
return;
}
KeyHandler.sInCallRinging = false;
}
}
};
/* access modifiers changed from: private */
public ScreenHelper mSwitchHelper;
/* access modifiers changed from: private */
public Handler mSwitchScreenHandler;
private WakeLock mSwitchWakeLock;
/* access modifiers changed from: private */
public TelephonyManager mTelephonyManager;
private final Vibrator mVibrator;
class SettingsObserver extends ContentObserver {
public SettingsObserver(Handler handler) {
super(handler);
}
/* access modifiers changed from: 0000 */
public void observe() {
ContentResolver contentResolver = KeyHandler.this.mContext.getContentResolver();
contentResolver.registerContentObserver(System.getUriFor(KeyHandler.WAKE_FRONT_ON_CALL), false, this, -1);
contentResolver.registerContentObserver(System.getUriFor(KeyHandler.FORCE_FRONT_ON_CALL), false, this, -1);
contentResolver.registerContentObserver(System.getUriFor(KeyHandler.FINGER_SWITCH_SETTING_KEY), false, this, -1);
update();
}
public void onChange(boolean z) {
update();
}
/* access modifiers changed from: 0000 */
public void update() {
ContentResolver contentResolver = KeyHandler.this.mContext.getContentResolver();
boolean z = true;
KeyHandler.sPressSwitch = System.getInt(contentResolver, KeyHandler.FINGER_SWITCH_SETTING_KEY, 1) == 1;
KeyHandler.sWakeFrontOnRinging = System.getInt(contentResolver, KeyHandler.WAKE_FRONT_ON_CALL, 1) == 1;
if (System.getInt(contentResolver, KeyHandler.FORCE_FRONT_ON_CALL, 1) != 1) {
z = false;
}
KeyHandler.sForceFrontOnRinging = z;
}
}
private class SwitchRunnable implements Runnable {
private long mSwitchCompleteTime = 0;
private int mTarget;
public SwitchRunnable(int i) {
this.mTarget = i;
}
public void run() {
if (this.mTarget != ScreenHelper.getHelper().getCurrentDisplayId()) {
doSwitch();
}
}
private void doSwitch() {
if (this.mSwitchCompleteTime > 0 && SystemClock.uptimeMillis() - this.mSwitchCompleteTime < 50) {
try {
Thread.sleep(Math.abs(SystemClock.uptimeMillis() - this.mSwitchCompleteTime));
} catch (Exception e) {
}
}
KeyHandler.this.mSwitchHelper.setCurrentDisplay(this.mTarget);
readLcdState(this.mTarget);
KeyHandler.this.mMotionDetector.setCurrentDisplayId(this.mTarget);
FileUtils.writeLine("/sys/class/backlight/panel0-backlight/brightness", FileUtils.readOneLine("/sys/class/backlight/panel0-backlight/brightness"));
this.mSwitchCompleteTime = SystemClock.uptimeMillis();
}
private void readLcdState(int i) {
int i2 = 0;
while (i2 < 200) {
int parseInt = Integer.parseInt(FileUtils.readOneLine("/sys/kernel/lcd_enhance/lcd_state"));
if (i == parseInt || parseInt > 1) {
i2++;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
return;
}
}
}
}
public KeyHandler(Context context) {
this.mContext = context;
this.mVibrator = (Vibrator) context.getSystemService(Vibrator.class);
this.mPowerManager = (PowerManager) context.getSystemService(PowerMenuConstants.GLOBAL_ACTION_KEY_POWER);
this.mSwitchWakeLock = this.mPowerManager.newWakeLock(1, "NubiaPartsGestureWakeLock:");
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.SCREEN_OFF");
intentFilter.addAction("android.intent.action.SCREEN_ON");
intentFilter.addAction("android.intent.action.PHONE_STATE");
context.registerReceiver(this.mScreenStateReceiver, intentFilter);
this.mSwitchHelper = ScreenHelper.getHelper();
this.mSwitchScreenHandler = new Handler(this.mSwitchHelper.getLooper());
initMotionDetector();
initSettingsObserver();
}
private void initSettingsObserver() {
new SettingsObserver(new Handler()).observe();
}
private void initMotionDetector() {
this.mMotionDetector = new MotionDetector(this.mContext);
this.mMotionDetector.setMotionListener(new MotionListener() {
public void onMotionChange(int i) {
if (KeyHandler.sScreenTurnedOn) {
KeyHandler.this.mSwitchScreenHandler.post(new SwitchRunnable(i));
}
}
});
this.mMotionDetector.setCurrentDisplayId(ScreenHelper.getHelper().getCurrentDisplayId());
}
public KeyEvent handleKeyEvent(KeyEvent keyEvent) {
if (!hasSetupCompleted()) {
return keyEvent;
}
if (this.keyguardManager == null) {
this.keyguardManager = (KeyguardManager) this.mContext.getSystemService(KeyguardManager.class);
}
if (this.keyguardManager.isKeyguardLocked() || !sScreenTurnedOn) {
return keyEvent;
}
int keyCode = keyEvent.getKeyCode();
if (keyCode != 133 && keyCode != 134) {
return keyEvent;
}
boolean z = true;
if (keyEvent.getAction() != 1) {
z = false;
}
if (z) {
return interceptFpKeyUp(keyEvent);
}
return interceptFpKeyDown(keyEvent);
}
private KeyEvent interceptFpKeyDown(KeyEvent keyEvent) {
switch (keyEvent.getKeyCode()) {
case 133:
if (!this.mLeftKeyPressed && (keyEvent.getFlags() & 1024) == 0) {
this.mLeftKeyPressed = true;
this.mLeftFpDownTime = keyEvent.getDownTime();
triggerDoubleFpAction();
break;
}
case 134:
if (!this.mRightKeyPressed && (keyEvent.getFlags() & 1024) == 0) {
this.mRightKeyPressed = true;
this.mRightFpDownTime = keyEvent.getDownTime();
triggerDoubleFpAction();
break;
}
}
return null;
}
private KeyEvent interceptFpKeyUp(KeyEvent keyEvent) {
switch (keyEvent.getKeyCode()) {
case 133:
this.mLeftKeyPressed = false;
this.mLeftFpDownTime = 0;
break;
case 134:
this.mRightKeyPressed = false;
this.mRightFpDownTime = 0;
break;
}
if (this.mMotionDetector.isEnable()) {
this.mMotionDetector.disable();
}
return null;
}
private void triggerDoubleFpAction() {
if (this.mLeftKeyPressed && this.mRightKeyPressed && sPressSwitch) {
long uptimeMillis = SystemClock.uptimeMillis();
if (uptimeMillis <= this.mLeftFpDownTime + DEBOUNCE_DELAY_MILLIS && uptimeMillis <= this.mRightFpDownTime + DEBOUNCE_DELAY_MILLIS) {
this.mSwitchWakeLock.acquire(3000);
doHapticFeedback();
this.mMotionDetector.enable();
}
}
}
private void doHapticFeedback() {
if (this.mVibrator != null && this.mVibrator.hasVibrator()) {
this.mVibrator.vibrate(50);
}
}
private boolean hasSetupCompleted() {
return Secure.getInt(this.mContext.getContentResolver(), "user_setup_complete", 0) != 0;
}
}
Sorry for my bad english!
Thanks!
Tom04 said:
Hello there!
I would need some help reverse engineering an app and recompiling it with some different code afterwards.
The App coordinates all the different components of my phone to work properly.
When you press the two fingerprint sensors, the app gives you haptic feedback and turns the screen from front to back or vice versa, depending on which side is facing up.
I need the app to do exactly that once when i wake up my phone either with fingerprint or power button, so the display illuminates which is facing up, and not the one i used recently.
I have some experience with java, but all i got are the .smali documents.
Is there any way to reliably get smali into java and back?
Code:
Sorry for my bad english!
Thanks!
Click to expand...
Click to collapse
Try APKtool, open source, most used out there.
"apktool d (nameof the app).apk"
"apktool b (name of the app).apk" to recompile
If it's a system file, make sure you don't modify the original signature by adding -c to the last command.
Have a good day

Someone can tell me why it wouldn't show USB disk mount after I first read USB disk message?

My OS: Android9
Fuction: Showing USB disk's images and copy images to this device when I insert the usb disk
My question:
1.It can read the disk's path and name when I first insert the usb disk, but I can't showing the image from the disk whether using setImageBitmap(bitmap) and setImageURI(uri) of ImageView control
2.It can't show the path on the adb : /mnt/media_rw/, in commont it is will show the usb disk's name , like this: mnt/media_rw/20D3-1E69
my code is below, someone can help me , thanks!
Java:
public class TestActivity2 extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityLoginBinding = ActivityLoginBinding.inflate(LayoutInflater.from(this));
setContentView(activityLoginBinding.getRoot());
activityLoginBinding.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendBroadcast(new Intent(ACTION_USB_PERMISSION));
}
});
}
/**
* 读取u盘文件
* @param device UsbMassStorageDevice实例对象
*/
private void readAllPicFromUSB(UsbMassStorageDevice device) {
// listImageUSBInfo.clear(); //清空list初始化
try { //遍历文件名
device.init();
// 设备分区
partition = device.getPartitions().get(0);
// 文件系统
currentFs = partition.getFileSystem();
// 获取 U 盘的根目录
mRootFolder = currentFs.getRootDirectory();
readAllPicFromUSB(mRootFolder,currentFs); //递归读取文件
Log.i(TAG, "picSize:" + picSize);
Log.i(TAG,"all pic count:" + picCount + ",all size:" + (long)(picSize / 1024) + "M"); //单位大小为M
picCount = 0; //归零
//所有文件加入list后通知livew刷新
Log.i(TAG,"list size----------------" + listImageUSBInfo.size());
sendBroadcast(new Intent(ACTION_USB_UPDATE_LISTVIEW));
//
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "readDevice error:" + e.toString());
}
return;
}
/**
* 获取 U盘读写权限的申请
* @param context 上下文对象
*/
private void permissionRequest(Context context) {
Log.i(TAG,"开始申请设备权限");
try {
// 设备管理器
UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
// 获取 U 盘存储设备
UsbMassStorageDevice[] storageDevices = UsbMassStorageDevice.getMassStorageDevices(context.getApplicationContext());
PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(),
0, new Intent(ACTION_USB_PERMISSION), 0);
if(storageDevices.length == 0){
Log.i(TAG,"请插入可用的 U 盘");
}else{
//可能有几个 一般只有一个 因为大部分手机只有1个otg插口
for (UsbMassStorageDevice device : storageDevices) {
if (usbManager.hasPermission(device.getUsbDevice())) {
Log.i(TAG,"USB已经获取权限");
} else {//无权限申请权限
usbManager.requestPermission(device.getUsbDevice(), pendingIntent);
}
}
}
} catch (Exception e) {
Log.i(TAG,"申请权限异常:" +e.toString());
}
}//end permissionRequest
/**
* USBDevice 转换成UsbMassStorageDevice 对象
* @param usbDevice UsbDevice对象
*/
private UsbMassStorageDevice getUsbMass(UsbDevice usbDevice) {
UsbMassStorageDevice[] storageDevices = UsbMassStorageDevice.getMassStorageDevices(mContext);
for (UsbMassStorageDevice device : storageDevices) {
if (usbDevice.equals(device.getUsbDevice())) {
return device;
}
}
return null;
}//end
@Override
protected void onResume() {
super.onResume();
initUSBService();
Log.i(TAG,"enter onResume");
}//end onresume
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(usbBroadcast); //注销广播
}
private void initUSBService() { //初始化广播监听器
usbDeviceStateFilter = new IntentFilter();
usbDeviceStateFilter.addAction(ACTION_USB_IN);
usbDeviceStateFilter.addAction(ACTION_USB_OUT);
usbDeviceStateFilter.addAction(ACTION_USB_PERMISSION);
usbDeviceStateFilter.addAction(ACTION_USB_UPDATE_LISTVIEW);
registerReceiver(usbBroadcast,usbDeviceStateFilter);
}
/**
* 广播监听u盘拔插情况
*/
private BroadcastReceiver usbBroadcast = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mContext=context;
String action=intent.getAction();
switch (action){
case ACTION_USB_PERMISSION: //自定义广播读取u盘文件
try {
UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED,
false)){
Log.i(TAG,"已经有权限111111111111");
if (usbDevice != null) {
readAllPicFromUSB(getUsbMass(usbDevice)); //读取u盘文件
}
else
Log.i(TAG,"没有插入U盘");
}else {
Log.i(TAG,"没有获取读写权限!,开始获取22222222222222");
permissionRequest(mContext); //获取权限
}
}catch (Exception e){
Log.i(TAG, "ACTION_USB_PERMISSION error:" + e.toString());
}
break;
case ACTION_USB_IN:
Log.i(TAG, "插入了u盘");
break;
case ACTION_USB_OUT:
Log.i(TAG,"拔出了u盘");
break;
}
}
};
/**
* 获取本机设备读写权限
*/
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
private static int REQUEST_PERMISSION_CODE = 1;
private int ANDROID_VERSION_CURRENT = Build.VERSION.SDK_INT;
private void requestReadAndWriteAccess() {
Log.i(TAG,"now android version is :" + ANDROID_VERSION_CURRENT);
if (ANDROID_VERSION_CURRENT > Build.VERSION_CODES.LOLLIPOP){
if(ActivityCompat.checkSelfPermission(TestActivity2.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(TestActivity2.this, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);
Log.i(TAG,"已经获取读写权限");
}
}
}//end requestReadAndWriteAccess
/**
* 递归读取u盘文件图片文件
* @param usbFile 根文件夹
* @param fileSystem 文件系统
*/
private void readAllPicFromUSB(UsbFile usbFile, FileSystem fileSystem) {
try {
long tmp = 0;
String imgPath = "";
String imgName = "";
UsbFile[] usbFileList = usbFile.listFiles();
for (UsbFile usbFileItem:usbFileList){
if (!usbFileItem.isDirectory()){
String FileEnd = usbFileItem.getName().substring(usbFileItem.getName().lastIndexOf(".") + 1,
usbFileItem.getName().length()).toLowerCase(); //后缀名
if(FileEnd.equals("jpg") || FileEnd.equals("png") || FileEnd.equals("gif")
|| FileEnd.equals("jpeg")|| FileEnd.equals("bmp")){ //过滤出照片
tmp = usbFileItem.getLength() / 1024;
imgPath = USB_PATH_PREFIX + usbFileItem.getAbsolutePath(); //需要绝对地址
imgName = usbFileItem.getName();
Log.i(TAG,"img name:" + imgName + ",path:" + imgPath + ",size:" + tmp + "K");
picCount++;
picSize += tmp; //大小为K
// 加入到list
listImageUSBInfo.add(new ImageInfo(imgPath,imgName));
}
}else
readAllPicFromUSB(usbFileItem,fileSystem);
}
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG,"readDevice error:"+e.toString());
}
}//end
}

Categories

Resources