I have been experiencing this issue for quite a while and even after googling a while, I havent found a reasonable solution for my problem.
The issue I am experiencing is that the SurfaceView I am using flickers. Once in a while, the objects I draw flicker and they change their size or colour.
It looks like that sometimes the application skips my calls to 'Paint.setColor()' and the one to 'Paint.setStrokeWidth()'.
I have made methods which change the used paint and then, in order to try to fix this issue, to set it back to the default paint values. Still the issue persists. I have also read that the problem might be due to the double buffering. Is it the case? I am using this code for the DrawingThread:
PS. u can notice that I also tried to use a dirty Rectangle to try to see if the issue can be fixed, but still nothing. [I might not have understood what it actually does.
Code:
class DrawingThread extends Thread {
private SurfaceHolder _surfaceHolder;
private CustomView _cv;
private boolean _run = false;
public DrawingThread(SurfaceHolder surfaceHolder, CustomView cv) {
super();
_surfaceHolder = surfaceHolder;
_cv = cv;
}
public void setRunning(boolean run) {
_run = run;
}
public boolean isRunning() {
return _run;
}
public SurfaceHolder getSurfaceHolder() {
return _surfaceHolder;
}
@Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
//c = _surfaceHolder.lockCanvas(new Rect(lon - range, lon + range, lat - range, lat + range));
c = _surfaceHolder.lockCanvas();
synchronized (_surfaceHolder) {
_cv.onDraw(c);
}
} finally {
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
PS. I have read somewhere I should draw on a single bitmap and then draw the bitmap on the canvas. I have tried several times but I cannot manage to do so.
Thanks in advance,
N.
Is there anyone who can help me?
Could someone give me a hand?
I cannot find the reason why I cannot fix this issue.
I have tried to draw the items on a bitmap first and then adding it to the canvas, but I didnt manage and I either get a white canvas or a completely black one.
I believe the issue is quite easy to solve after you do it once.
Not even someone who could give some suggestions?
Hey!
As far as I can see the code you posted looks fine. Can you please post the code of your CustomView class? I think there could be an issue there.
Are you trying to make a game?
Hello!!!!
Finally someone
Here is the code I use for the onDraw(canvas):
Code:
@Override
public void onDraw(Canvas canvas) {
try {
canvas.drawColor(Color.WHITE);
pt.setAntiAlias(true);
canvas.rotate(-90, 0, 0);
canvas.translate(translateX, translateY);
canvas.scale(scale, scale);
canvas.rotate(-rotation, lat, lon);
// Drawing Points
Renderer.drawStreet(gaia.getStreets(), scale, canvas, pt);
Renderer.drawPolygon(gaia.getPolygons(), canvas, pt);
Renderer.drawPOI(myContext, gaia.getPOIs(), canvas, pt, scale, rotation);
Renderer.drawCustomPOI(myContext, gaia.getCustomPOI(), canvas, pt, scale, rotation);
if (showLocation) {
drawMarker(canvas);
}
if(drivingMode)
{
Renderer.drawRoute(gaia.getRoute(), canvas, pt);
}
} catch (Exception e) {
e.printStackTrace();
}
}
This is actually a map renderer.
I know the issue is very likely to be due to the double buffering, but I cannot find a way to fix it.
Thanks!
N.
Can you please post the code for the callback methods (onSurfaceCreated, onSurfaceChanged, onSurfaceDestroyed) and maybe the constructor for the view too? I think the problem could be due to the setting up and not the actual rendering.
How are you accessing the surfaceHolder. Are you using the getHolder() method for that? And are you sending the reference you get to the surfaceHolder from getHolder() to the DrawingThread?
Here is the light version of the code:
Code:
public class CustomMapView extends SurfaceView implements
SurfaceHolder.Callback, LocationListener {
private DrawingThread _thread;
private RenderingThread _threadStreets;
Context myContext;
Paint pt = new Paint();
final int SCREEN_HEIGHT = 600;
final int SCREEN_WIDTH = 480;
float scale;
int range = 100000;
static public int rotation = 0;
int sensibility = 100;
int lat;
int lon;
float translateX = -lat * scale - SCREEN_HEIGHT / 2;
float translateY = -lon * scale + SCREEN_WIDTH / 2;
boolean followLocation = true;
boolean isZooming = false;
boolean showLocation = true;
boolean followRotation = false;
static boolean drivingMode = false;
boolean DEBUG = true;
Handler mHandler;
public static GaiaApp gaia;
public CustomMapView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
gaia = ((GaiaApp) context.getApplicationContext());
scale = gaia.getCurScale();
lat = (int) gaia.getCurPosition().getLatitude();
lon = (int) gaia.getCurPosition().getLongitude();
pf = new PathFinder();
startupDB();
myContext = context;
mHandler = new Handler();
_thread = new DrawingThread(getHolder(), this);
_threadStreets = new RenderingThread(this);
setFocusable(true);
pt.setFlags(Paint.DITHER_FLAG);
pt.setFilterBitmap(true);
this.invalidate();
}
@Override
public void onDraw(Canvas canvas) {
try {
canvas.drawColor(Color.WHITE);
pt.setAntiAlias(true);
canvas.rotate(-90, 0, 0);
canvas.translate(translateX, translateY);
canvas.scale(scale, scale);
canvas.rotate(-rotation, lat, lon);
// Drawing Points
Renderer.drawStreet(gaia.getStreets(), scale, canvas, pt);
Renderer.drawPolygon(gaia.getPolygons(), canvas, pt);
Renderer.drawPOI(myContext, gaia.getPOIs(), canvas, pt, scale, rotation);
Renderer.drawCustomPOI(myContext, gaia.getCustomPOI(), canvas, pt, scale, rotation);
if (showLocation) {
drawMarker(canvas);
}
if(drivingMode)
{
Renderer.drawRoute(gaia.getRoute(), canvas, pt);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (!_thread.isRunning()) {
_thread.setRunning(true);
_thread.start();
}
if (!_threadStreets.isRunning()) {
_threadStreets.setRunning(true);
_threadStreets.start();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
_thread.setRunning(false);
_threadStreets.setRunning(false);
while (retry) {
try {
_thread.join();
_threadStreets.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
class DrawingThread extends Thread {
private SurfaceHolder _surfaceHolder;
private CustomMapView _cmv;
private boolean _run = false;
public DrawingThread(SurfaceHolder surfaceHolder, CustomMapView cmv) {
super();
_surfaceHolder = surfaceHolder;
_cmv = cmv;
}
public void setRunning(boolean run) {
_run = run;
}
public boolean isRunning() {
return _run;
}
public SurfaceHolder getSurfaceHolder() {
return _surfaceHolder;
}
@Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas();
synchronized (_surfaceHolder) {
_cmv.onDraw(c);
}
} finally {
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
class RenderingThread extends Thread {
CustomMapView _cmv;
Boolean _run = false;
public RenderingThread(CustomMapView cmv) {
super();
_cmv = cmv;
}
public void setRunning(boolean run) {
_run = run;
}
public boolean isRunning() {
return _run;
}
@Override
public void run() {
while (_run) {
try {
Log.d("CustomMapView", "Retrieving...");
new StreetRunnable(_cmv).run();
Log.d("CustomMapView", "Retrieving");
if(!followRotation)
rotation = 0;
else
rotation = gaia.getOrientation();
Log.d("CustomMapView", "Updating...");
mHandler.post(new Runnable() {
@Override
public void run() {
_cmv.invalidate();
}
});
Log.d("CustomMapView", "Updated");
} finally {
}
}
}
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
Hello,
have you had the chance to check it out?
Thanks
N.
Sorry about that. I did not have access to the internet for the last 2 - 3 days.
Anyways I went through your code...If that is what you call light I wouldn't want to know whats heavy
I noticed that you have two threads which are responsible for drawing to the same view. You are using the DrawingThread to call the onDraw method of your CustomMapView object and the RenderingThread to post the invalidate method of the same CustomMapView object, which also results in a call to the onDraw method of the same view.
I am not really sure if doing this is a good thing and maybe this is what is causing the problems with the rendering? As a test, you could comment out one of the Thread.start() calls to one of the two rendering threads in your onSurfaceCreated method and check if it stops flickering.
I know this isn't how you want your app to function but if it fixes the flickering you'd know its the the two drawing threads that are causing the problem.
Code:
@Override
public void surfaceCreated(SurfaceHolder holder) {
// Comment out either one of the following two if blocks
if (!_thread.isRunning()) {
_thread.setRunning(true);
_thread.start();
}
if (!_threadStreets.isRunning()) {
_threadStreets.setRunning(true);
_threadStreets.start();
}
}
Awesome dude!
It fixed it straight away.
The reason is that I got a thread first and then added a new one, without thinking about just merging them both together
Thanks again!
Yep. You're welcome!
You'll just have to redesign your code to use just one rendering thread and it should work fine. All the best!
I am developing an application which draws the path of the user as he moves and calculates the area .
This is the code i am trying my problem is at the start of recording the path the path is drawn even if the user has not moved and sometimes when even if user is moving the path is not drawn .
RouteOverlay class:
public class RouteOverlay extends Overlay {
private GeoPoint gp1;
private GeoPoint gp2;
private int mode = 1;
public RouteOverlay(GeoPoint paramGeoPoint1, GeoPoint paramGeoPoint2,int paramInt)
{
this.gp1 = paramGeoPoint1;
this.gp2 = paramGeoPoint2;
this.mode = paramInt;
}
public void draw(Canvas paramCanvas, MapView paramMapView,
boolean paramShadow)
{
super.draw(paramCanvas, paramMapView, paramShadow);
Projection projection = paramMapView.getProjection();
Paint mPaint = new Paint();
mPaint.setDither(true);
mPaint.setAntiAlias(true);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(3);
mPaint.setAlpha(120);
Point p1 = new Point();
Point p2 = new Point();
Path path = new Path();
projection.toPixels(gp1, p1);
projection.toPixels(gp2, p2);
path.moveTo(p2.x,p2.y);
path.lineTo(p1.x,p1.y);
paramCanvas.drawPath(path, mPaint);
}
MainActivity:
public class MainActivity extends MapActivity {
public final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
coordinates.add(location);
mapView.getController().animateTo(getGeoByLocation(location));
drawRoute(coordinates, mapView);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_area_measurement);
this.mapView = ((MapView) findViewById(R.id.mapview));
this.mapView.setBuiltInZoomControls(false);
this.mapView.getController().setZoom(17);
this.coordinates = new ArrayList<Location>();
}
protected boolean isRouteDisplayed() {
return false;
}
private GeoPoint getGeoByLocation(Location location) {
GeoPoint gp = null;
try {
if (location != null) {
double geoLatitude = location.getLatitude() * 1E6;
double geoLongitude = location.getLongitude() * 1E6;
gp = new GeoPoint((int) geoLatitude, (int) geoLongitude);
}
} catch (Exception e) {
e.printStackTrace();
}
return gp;
}
public String getLocationProvider(LocationManager paramLocationManager) {
try {
Criteria localCriteria = new Criteria();
localCriteria.setAccuracy(1);
localCriteria.setAltitudeRequired(false);
localCriteria.setBearingRequired(false);
localCriteria.setCostAllowed(true);
localCriteria.setPowerRequirement(3);
String str = paramLocationManager.getBestProvider(localCriteria,
true);
return str;
} catch (Exception localException) {
while (true) {
localException.printStackTrace();
}
}
}
private void drawRoute(ArrayList<Location> paramArrayList,MapView paramMapView) {
List<Overlay> overlays = paramMapView.getOverlays();
//Changed for smooth rendering
overlays.clear();
for (int i = 1; i < paramArrayList.size(); i++) {
overlays.add(new RouteOverlay(getGeoByLocation(paramArrayList.get(i - 1)), getGeoByLocation(paramArrayList.get(i)),2));
}
}
public void startRecording() {
this.isMeasuring = true;
lm = (LocationManager) getSystemService(LOCATION_SERVICE);
lm.requestLocationUpdates(getLocationProvider(lm),500,2,this.locationListener);
/*if (lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
gpsstatus.setText("Gps Is Enabled");
}else
{ gpsstatus.setText("Gps Is disabled");}*/
}
This probably has to do with the accuracy of the GPS. I didn't really look at your code but maybe you should add some kind of buffer. if (movement>5m){//draw stuff}
I have this code below. The problem is i set the orientation of camera to portrait, even preview is portrait. But when i playback that video i see it in landscape mode. Do you guys know why and how i can fix this? Is there a way to rotate VideoView when i playback or to rotate video itself after recording..? I beg you, help me, anywhere i ask nobody knows why and how to fix it...
Here is the code:
Code:
public class BetaRecordActivity extends Activity {
private Preview preview;
private Camera camera;
private MediaRecorder recorder;
private int defaultCameraId;
private int videoCount;
[user=439709]@override[/user]
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.beta_record, menu);
return true;
}
[user=439709]@override[/user]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_beta_record);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
initCameraAndPreview();
videoCount = 0;
preview.setOnTouchListener(new View.OnTouchListener() {
[user=439709]@override[/user]
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
releaseCamera();
getThatCamReady();
recorder.start();
videoCount ++;
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
stopRecording();
break;
}
return true;
}
});
}
[user=439709]@override[/user]
protected void onResume() {
super.onResume();
}
[user=439709]@override[/user]
protected void onPause() {
super.onPause();
}
private boolean getThatCamReady() {
camera = getCameraInstance();
setCameraDisplayOrientation(this, defaultCameraId, camera);
camera.unlock();
recorder = new MediaRecorder();
recorder.setCamera(camera);
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
File tempFile = new File(Environment.getExternalStorageDirectory(), "/rec/temp/video_" + String.valueOf(videoCount) + ".mp4");
recorder.setOutputFile(tempFile.getPath());
recorder.setMaxDuration(12500);
recorder.setMaxFileSize(7000000);
recorder.setPreviewDisplay(preview.getHolder().getSurface());
try {
recorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}
private void stopRecording() {
//timer.pause();
try {
recorder.stop();
} catch(RuntimeException stopException) {
// Handle the cleanup here
//badList.add(videoCount);
//videoCount--;
//RecordActivity.this.timeLeft.setText(String.valueOf(videoCount));
}
releaseMediaRecorder();
}
private void initCameraAndPreview() {
// Find the total number of cameras available
int numberOfCameras = Camera.getNumberOfCameras();
// Find the ID of the default camera
CameraInfo cameraInfo = new CameraInfo();
for (int i = 0; i < numberOfCameras; i++) {
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
defaultCameraId = i;
}
}
camera = getCameraInstance();
setCameraDisplayOrientation(this, defaultCameraId, camera);
preview = new Preview(this, camera);
FrameLayout myCameraPreview = (FrameLayout)findViewById(R.id.videoview);
myCameraPreview.addView(preview);
}
private void releaseMediaRecorder(){
if (recorder != null) {
recorder.reset();
recorder.release();
recorder = null;
camera.lock();
}
}
private void releaseCamera(){
if (camera != null){
camera.release();
camera = null;
}
}
private Camera getCameraInstance(){
// TODO Auto-generated method stub
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
}
Hi,
I´ve a big problem with the "getScanResults()" function. I always get "0" as result.
Here is my Code (it´s a service):
Code:
public void onCreate() {
super.onCreate();
wifiMgr = (WifiManager)getSystemService(Context.WIFI_SERVICE);
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext());
intentScan = new IntentFilter();
intentScan.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
scanReceiver = new ScanReceiver();
screenOnReceiver = new ScreenOnReceiver();
registerReceiver(screenOnReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
screenOffReceiver = new ScreenOffReceiver();
registerReceiver(screenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
}
[user=439709]@override[/user]
public void onDestroy () {
unregisterReceiver(screenOnReceiver);
unregisterReceiver(screenOffReceiver);
}
[user=439709]@override[/user]
public void onStart(Intent intent, int startId) {
wifiMgr = (WifiManager)getSystemService(Context.WIFI_SERVICE);
registerReceiver(scanReceiver, intentScan);
showToasts = sharedPreferences.getBoolean("checkbox_notification", true);
autoSync = sharedPreferences.getBoolean("checkbox_autosync", true);
if(wifiMgr.getConnectionInfo().getNetworkId() == -1) {
if(wifiMgr.setWifiEnabled(true)) {
if(!wifiMgr.startScan()){
unregisterReceiver(scanReceiver);
}
}
}else{
if(showToasts)
Toast.makeText(this.getApplicationContext(),R.string.toast_nochange, Toast.LENGTH_SHORT).show();
}
}
public class ScanReceiver extends BroadcastReceiver {
[user=439709]@override[/user]
public void onReceive(Context context, Intent intent) {
Log.d("wifi", "ScanComplete - "+intent.getAction());
List<WifiConfiguration> wifiListSupplicant = wifiMgr.getConfiguredNetworks();
List<ScanResult> wifiListScan = wifiMgr.getScanResults();
Log.d("wifi", "LIST: "+wifiListScan.size());
} }
Somebody an idea?
Thanks"
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