[Q]get the message “Only the original thread that created a view hierarchy can touch - Android Q&A, Help & Troubleshooting

hi,
I hvae very spcieal problem, i read all the post on multithreading in android, but still go the famuse error. but, i got in after the second run of the same thread for exmaple "thGetDevice" from the sourcecode;
hope u can help me.. thnx..
Code:
/** Variable definition*/
CheckBox cbBlueTooth;
BluetoothAdapter mBluetoothAdapter;
AlertDialog.Builder dialog;
ArrayAdapter<String> mArrayAdapter;
ListView MainListView;
ProgressBar prProgressbar;
Thread thGetDevices;
Thread thClearDevices;
Handler handler;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Initial Handler */
handler=new Handler() {
@SuppressWarnings("unchecked")
@Override
public void handleMessage(Message msg) {
prProgressbar.incrementProgressBy(msg.arg1);
mArrayAdapter = (ArrayAdapter<String>)msg.obj;
mArrayAdapter.notifyDataSetInvalidated();
mArrayAdapter.notifyDataSetChanged();
prProgressbar.setVisibility(ProgressBar.INVISIBLE);
/******************************
*
* this line cuse to the trouble
*/
setListAdapter(mArrayAdapter);
thClearDevices=null;
thGetDevices = null;
}
};
/* Set Finalization true */
// System.runFinalizersOnExit(true);
setContentView(R.layout.main);
/* ListView Definition */
TextView tvHeader = new TextView(this);
MainListView = this.getListView();
MainListView.addHeaderView(tvHeader);
mArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
//mArrayAdapter.setNotifyOnChange(true);
prProgressbar = (ProgressBar)findViewById(R.id.progressBar1);
prProgressbar.setVisibility(ProgressBar.INVISIBLE);
/* Get Bluetooth driver */
cbBlueTooth = (CheckBox)findViewById(R.id.cbTurnBlueTooth);
dialog = new AlertDialog.Builder(this);
/* initializing Bluetooth adapter **/
mBluetoothAdapter= BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
/*ShowNotifMessage("Sorry..", "You Don't have Bluetooth Driver");
try {
Thread.sleep(3000);
android.os.Process.killProcess(android.os.Process.myPid());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
// Initial the thGetDeviceThread and thClearDevices
//initGetDevicesThread();
//initClearDevicesThread();
/*Listener for Checkbox*/
cbBlueTooth.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if (isChecked && !mBluetoothAdapter.isEnabled()) {
prProgressbar.setVisibility(ProgressBar.VISIBLE);
buttonView.setEnabled(false);
BluetoothAdapter.getDefaultAdapter().enable();
initGetDevicesThread();
buttonView.setEnabled(true);
}
else if (!isChecked && mBluetoothAdapter.isEnabled()) {
prProgressbar.setVisibility(ProgressBar.VISIBLE);
buttonView.setEnabled(false);
BluetoothAdapter.getDefaultAdapter().disable();
initClearDevicesThread();
buttonView.setEnabled(true);
}
else
{
prProgressbar.setVisibility(ProgressBar.VISIBLE);
buttonView.setEnabled(false);
BluetoothAdapter.getDefaultAdapter().enable();
initGetDevicesThread();
buttonView.setEnabled(true);
}
}
});
}
/** Gets all paird devices and put them in the Listview */
private void initGetDevicesThread()
{
thGetDevices = new Thread(new Runnable() {
public void run() {
Message msg = handler.obtainMessage();
msg.obj = getDeviceList();
handler.sendMessage(msg);
}
});
(thGetDevices).start();
}
/** clear all paird devices and put them in the Listview */
private void initClearDevicesThread()
{
thClearDevices = new Thread(new Runnable() {
public void run() {
Message msg = handler.obtainMessage();
msg.obj = clearListOfDevices();
handler.sendMessage(msg);
}
});
(thClearDevices).start();
}
public ArrayAdapter<String> getDeviceList()
{
while(BluetoothAdapter.getDefaultAdapter().getState() != BluetoothAdapter.STATE_ON);
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName());
}
}
return mArrayAdapter;
}
private ArrayAdapter<String> clearListOfDevices()
{
while(BluetoothAdapter.getDefaultAdapter().getState() != BluetoothAdapter.STATE_OFF);
mArrayAdapter = new ArrayAdapter<String>(MainListView.getContext(), android.R.layout.simple_list_item_1);
return mArrayAdapter;
}
//** */
private void ShowNotifMessage(String strTitle,String strMsg)
{
dialog.setTitle(strTitle);
dialog.setMessage(strMsg);
dialog.show();
}

Please use the Q&A Forum for questions Thanks
Moving to Q&A

Related

Android - SurfaceView flickers and sometimes does not apply the proper paint

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!

[Q] Android Maps draw path problem

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}

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.

How to integrate Search Kit?

Article Introduction
In this article we will work in integrate search and will explore many features together in this service.
Search Kit
HUAWEI Search Kit fully opens Petal Search capabilities through the device-side SDK and cloud-side APIs, enabling ecosystem partners to quickly provide the optimal mobile app search experience.
Dependencies that needed
Code:
//design
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.github.bumptech.glide:glide:4.10.0'
//rxJava
implementation 'io.reactivex.rxjava2:rxjava:2.2.19'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
//searchKit HMS
implementation 'com.huawei.hms:searchkit:5.0.4.303'
1. Create a class that extends from Application
Code:
import android.app.Application
import com.huawei.hms.searchkit.SearchKitInstance
class SearchKitApplication: Application() {
override fun onCreate() {
super.onCreate()
// Initialize Search Kit.
SearchKitInstance.init(this, "your_app_id");
}
}
In Manifest in Application tag apply this below line of code
Code:
android:name=".SearchKitApplication"
3. Now we can create an empty activity with this name
SearchActivity. please take a look on important part in references.
or as you like you can modify it, if you would like.
4. In Utils package that we created in point 2, let’s create AnimationUtils class
Code:
public class AnimationUtils {
public static void expand(final View v) {
int matchParentMeasureSpec =
View.MeasureSpec.makeMeasureSpec(((View) v.getParent()).getWidth(), View.MeasureSpec.EXACTLY);
int wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
v.measure(matchParentMeasureSpec, wrapContentMeasureSpec);
final int targetHeight = v.getMeasuredHeight();
v.getLayoutParams().height = 1;
v.setVisibility(View.VISIBLE);
Animation a =
new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height =
interpolatedTime == 1
? ViewGroup.LayoutParams.WRAP_CONTENT
: (int) (targetHeight * interpolatedTime);
v.requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration((int) (targetHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
public static void collapse(final View v) {
final int initialHeight = v.getMeasuredHeight();
Animation a =
new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime == 1) {
v.setVisibility(View.GONE);
} else {
v.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime);
v.requestLayout();
}
}
@Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration((int) (initialHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
}
5. Now in network package let’s work on it to can get access token that will let us able to use search kit features
Code:
public class UrlHelper {
/**
* The Content REQUEST_TOKEN.
*/
public static final String REQUEST_TOKEN = "oauth2/v3/token";
// public static final String REQUEST_TOKEN = "oauth2/v2/token/https://logintestlf.hwcloudtest.cn/";
}
Code:
public interface QueryService {
@FormUrlEncoded
@POST(UrlHelper.REQUEST_TOKEN)
Observable<TokenResponse> getRequestToken(
@Field("grant_type") String grantType,
@Field("client_id") String ClientId,
@Field("client_secret") String clientSecret);
}
Code:
public class NetworkManager {
private static final String TAG = NetworkManager.class.getSimpleName();
private static NetworkManager networkManager;
public static NetworkManager getInstance() {
if (networkManager == null) {
syncInit();
}
return networkManager;
}
private static synchronized void syncInit() {
if (networkManager == null) {
networkManager = new NetworkManager();
}
}
public QueryService createService(Context context, String baseUrl) {
QueryService queryService = null;
Retrofit retrofit = null;
Retrofit.Builder builder = new Retrofit.Builder().baseUrl(baseUrl);
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
try {
SSLSocketFactory ssf = SecureSSLSocketFactory.getInstance(context);
X509TrustManager xtm = new SecureX509TrustManager(context);
clientBuilder.sslSocketFactory(ssf, xtm);
clientBuilder.hostnameVerifier(new StrictHostnameVerifier());
} catch (IOException e) {
Log.e(TAG, "getRetrofit: " + e.getMessage());
} catch (IllegalAccessException e) {
Log.e(TAG, "getRetrofit: " + e.getMessage());
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, "getRetrofit: " + e.getMessage());
} catch (KeyManagementException e) {
Log.e(TAG, "getRetrofit: " + e.getMessage());
} catch (KeyStoreException e) {
Log.e(TAG, "getRetrofit: " + e.getMessage());
} catch (CertificateException e) {
Log.e(TAG, "getRetrofit: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "getRetrofit: " + e.getMessage());
}
OkHttpClient client =
clientBuilder
.retryOnConnectionFailure(true)
.readTimeout(5000, TimeUnit.MILLISECONDS)
.connectTimeout(5000, TimeUnit.MILLISECONDS)
.build();
try {
retrofit =
builder.client(client)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
queryService = retrofit.create(QueryService.class);
} catch (Exception e) {
Log.e(TAG, "createRestClient error: " + e.getMessage());
}
return queryService;
}
}
6. In bean package, let’s start with create ListBean class
Code:
public class ListBean {
String title;
String url;
String click_url;
public String getClick_url() {
return click_url;
}
public void setClick_url(String click_url) {
this.click_url = click_url;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
Now we will work on create TokenResponse class:
Code:
public class TokenResponse {
String access_token;
Integer expires_in;
String token_type;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public Integer getExpires_in() {
return expires_in;
}
public void setExpires_in(Integer expires_in) {
this.expires_in = expires_in;
}
public String getToken_type() {
return token_type;
}
public void setToken_type(String token_type) {
this.token_type = token_type;
}
}
More details, you can visit https://forums.developer.huawei.com/forumPortal/en/topic/0204411812493980212
Hi i was following your sample, How can I obtain app id?
SearchKitInstance.init(this, "your_app_id");
Please help me

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