業界でAndroidを使用したい、
Slickdevlabs.comライブラリを使用して、ProfilicおよびFtdi USB to Serialチップに問題なく接続できます。
アプリケーションにはサービスがあり、起動時に起動し、USBシリアルポートに接続して他のことを行います。
私の問題は、ホストデバイスがユーザーと対話しないことです。
Android=が尋ねるとき
Allow the app "MyAPP" to access the USB device ?
[checkmark]Use by default for this USB device
Cancel OK
[OK]をクリックする人はいません。
デフォルトで使用をチェックしている場合でも...チェックボックス、USBを再挿入するか、ホストデバイスを再起動すると、次回の起動時に再度尋ねられます。
SuperUserモードでサービスとアプリを実行しましたが、違いはありません。もう一度尋ねます。
インテントフィルターを追加しましたが、違いはありません。毎回尋ねられます。
<intent-filter>
<action Android:name="Android.hardware.usb.action.USB_DEVICE_ATTACHED" />
<action Android:name="Android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
<meta-data
Android:name="Android.hardware.usb.action.USB_DEVICE_ATTACHED"
Android:resource="@xml/device_filter" />
<meta-data
Android:name="Android.hardware.usb.action.USB_DEVICE_DETACHED"
Android:resource="@xml/device_filter" />
それをバイパスまたは無効にする方法はありますか?
ルートおよびSUアクセスがあります。
もう少し遅れますが、それでも...
私は同じような問題を抱えていたので、なんとか解決できたと思います。 Androidが内部的に使用してUSBデバイスとアクセサリを管理できるサービスがあります。このサービスはサードパーティの開発者からは隠されており、文書化されていません。UsbPermissionActivityのソースサービスを呼び出すには、IUsbManagerインターフェースとServiceManagerクラスを使用します。これらは両方とも非表示になっているため、直接使用することはできません。しかし、スタブを作成するにはまったく同じ名前で、対応する名前空間(パッケージ)内にある場合は、ランタイム環境で実際のコードを使用しながら、そのコードをコンパイルできます。
唯一の要件は、アプリケーションはシステムのものでなければなりません-/ system/app /ディレクトリに配置する必要があります。デバイスはルート化されているため、問題はありません。
そのため、プロジェクトにパッケージを追加する必要があります: "Android.hardware.usb"そして、 "IUsbManager.Java"という名前のファイルを以下の内容で入れます:
package Android.hardware.usb;
public interface IUsbManager extends Android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends Android.os.Binder implements Android.hardware.usb.IUsbManager
{
/** Construct the stub at attach it to the interface. */
public Stub()
{
throw new RuntimeException( "Stub!" );
}
/**
* Cast an IBinder object into an Android.hardware.usb.IUsbManager interface,
* generating a proxy if needed.
*/
public static Android.hardware.usb.IUsbManager asInterface( Android.os.IBinder obj )
{
throw new RuntimeException( "Stub!" );
}
public Android.os.IBinder asBinder()
{
throw new RuntimeException( "Stub!" );
}
public boolean onTransact( int code, Android.os.Parcel data, Android.os.Parcel reply, int flags ) throws Android.os.RemoteException
{
throw new RuntimeException( "Stub!" );
}
static final int TRANSACTION_getDeviceList = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_openDevice = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_getCurrentAccessory = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_openAccessory = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_setDevicePackage = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
static final int TRANSACTION_setAccessoryPackage = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
static final int TRANSACTION_hasDevicePermission = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
static final int TRANSACTION_hasAccessoryPermission = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 7);
static final int TRANSACTION_requestDevicePermission = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 8);
static final int TRANSACTION_requestAccessoryPermission = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 9);
static final int TRANSACTION_grantDevicePermission = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 10);
static final int TRANSACTION_grantAccessoryPermission = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 11);
static final int TRANSACTION_hasDefaults = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 12);
static final int TRANSACTION_clearDefaults = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 13);
static final int TRANSACTION_setCurrentFunction = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 14);
static final int TRANSACTION_setMassStorageBackingFile = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 15);
}
/* Returns a list of all currently attached USB devices */
public void getDeviceList( Android.os.Bundle devices ) throws Android.os.RemoteException;
/* Returns a file descriptor for communicating with the USB device.
* The native fd can be passed to usb_device_new() in libusbhost.
*/
public Android.os.ParcelFileDescriptor openDevice( Java.lang.String deviceName ) throws Android.os.RemoteException;
/* Returns the currently attached USB accessory */
public Android.hardware.usb.UsbAccessory getCurrentAccessory() throws Android.os.RemoteException;
/* Returns a file descriptor for communicating with the USB accessory.
* This file descriptor can be used with standard Java file operations.
*/
public Android.os.ParcelFileDescriptor openAccessory( Android.hardware.usb.UsbAccessory accessory ) throws Android.os.RemoteException;
/* Sets the default package for a USB device
* (or clears it if the package name is null)
*/
public void setDevicePackage( Android.hardware.usb.UsbDevice device, Java.lang.String packageName ) throws Android.os.RemoteException;
/* Sets the default package for a USB accessory
* (or clears it if the package name is null)
*/
public void setAccessoryPackage( Android.hardware.usb.UsbAccessory accessory, Java.lang.String packageName ) throws Android.os.RemoteException;
/* Returns true if the caller has permission to access the device. */
public boolean hasDevicePermission(Android.hardware.usb.UsbDevice device) throws Android.os.RemoteException;
/* Returns true if the caller has permission to access the accessory. */
public boolean hasAccessoryPermission( Android.hardware.usb.UsbAccessory accessory ) throws Android.os.RemoteException;
/* Requests permission for the given package to access the device.
* Will display a system dialog to query the user if permission
* had not already been given.
*/
public void requestDevicePermission( Android.hardware.usb.UsbDevice device, Java.lang.String packageName, Android.app.PendingIntent pi ) throws Android.os.RemoteException;
/* Requests permission for the given package to access the accessory.
* Will display a system dialog to query the user if permission
* had not already been given. Result is returned via pi.
*/
public void requestAccessoryPermission( Android.hardware.usb.UsbAccessory accessory, Java.lang.String packageName, Android.app.PendingIntent pi ) throws Android.os.RemoteException;
/* Grants permission for the given UID to access the device */
public void grantDevicePermission( Android.hardware.usb.UsbDevice device, int uid ) throws Android.os.RemoteException;
/* Grants permission for the given UID to access the accessory */
public void grantAccessoryPermission( Android.hardware.usb.UsbAccessory accessory, int uid ) throws Android.os.RemoteException;
/* Returns true if the USB manager has default preferences or permissions for the package */
public boolean hasDefaults( Java.lang.String packageName ) throws Android.os.RemoteException;
/* Clears default preferences and permissions for the package */
public void clearDefaults( Java.lang.String packageName ) throws Android.os.RemoteException;
/* Sets the current USB function. */
public void setCurrentFunction( Java.lang.String function, boolean makeDefault ) throws Android.os.RemoteException;
/* Sets the file path for USB mass storage backing file. */
public void setMassStorageBackingFile( Java.lang.String path ) throws Android.os.RemoteException;
}
次に別のパッケージ: "Android.os" with "ServiceManager.Java":
package Android.os;
import Java.util.Map;
public final class ServiceManager
{
public static IBinder getService( String name )
{
throw new RuntimeException( "Stub!" );
}
/**
* Place a new @a service called @a name into the service
* manager.
*
* @param name the name of the new service
* @param service the service object
*/
public static void addService( String name, IBinder service )
{
throw new RuntimeException( "Stub!" );
}
/**
* Retrieve an existing service called @a name from the
* service manager. Non-blocking.
*/
public static IBinder checkService( String name )
{
throw new RuntimeException( "Stub!" );
}
public static String[] listServices() throws RemoteException
{
throw new RuntimeException( "Stub!" );
}
/**
* This is only intended to be called when the process is first being brought
* up and bound by the activity manager. There is only one thread in the process
* at that time, so no locking is done.
*
* @param cache the cache of service references
* @hide
*/
public static void initServiceCache( Map<String, IBinder> cache )
{
throw new RuntimeException( "Stub!" );
}
}
これらのクラスのインターフェースは、Androidのバージョンに応じて変わる可能性があることに注意してください。私の場合、バージョンは4.0.です。したがって、Androidの別のバージョンがあり、このコードが機能しない場合は、OSの特定のバージョンのソースコードを確認する必要があります。
サービスを使用してすべてのFTDIデバイスにアクセス許可を付与する例を次に示します。
import Java.util.HashMap;
import Java.util.Iterator;
import Android.content.BroadcastReceiver;
import Android.content.Context;
import Android.content.Intent;
import Android.content.pm.ApplicationInfo;
import Android.content.pm.PackageManager;
import Android.hardware.usb.IUsbManager;
import Android.hardware.usb.UsbDevice;
import Android.hardware.usb.UsbManager;
import Android.os.IBinder;
import Android.os.ServiceManager;
public class LaunchReceiver extends BroadcastReceiver
{
public void onReceive( Context context, Intent intent )
{
String action = intent.getAction();
if( action != null && action.equals( Intent.ACTION_BOOT_COMPLETED ) )
{
try
{
PackageManager pm = context.getPackageManager();
ApplicationInfo ai = pm.getApplicationInfo( YOUR_APP_PACKAGE_NAMESPACE, 0 );
if( ai != null )
{
UsbManager manager = (UsbManager) context.getSystemService( Context.USB_SERVICE );
IBinder b = ServiceManager.getService( Context.USB_SERVICE );
IUsbManager service = IUsbManager.Stub.asInterface( b );
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while( deviceIterator.hasNext() )
{
UsbDevice device = deviceIterator.next();
if( device.getVendorId() == 0x0403 )
{
service.grantDevicePermission( device, ai.uid );
service.setDevicePackage( device, YOUR_APP_PACKAGE_NAMESPACE );
}
}
}
}
catch( Exception e )
{
trace( e.toString() );
}
}
}
}
もう1つ-マニフェストに次のアクセス許可を追加する必要があります(Lintは気に入らないかもしれませんが、プロジェクトのプロパティで重大度をいつでも変更できます)。
<uses-permission Android:name="Android.permission.MANAGE_USB" />
@d_d_tの答えは素晴らしいですが、Android> 4.2.2。このインターフェースを使用してください:
public interface IUsbManager extends Android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends Android.os.Binder implements Android.hardware.usb.IUsbManager {
private static final Java.lang.String DESCRIPTOR = "Android.hardware.usb.IUsbManager";
/** Construct the stub at attach it to the interface. */
public Stub() {
throw new RuntimeException( "Stub!" );
}
/**
* Cast an IBinder object into an Android.hardware.usb.IUsbManager
* interface, generating a proxy if needed.
*/
public static Android.hardware.usb.IUsbManager asInterface( Android.os.IBinder obj) {
throw new RuntimeException( "Stub!" );
}
@Override
public Android.os.IBinder asBinder() {
throw new RuntimeException( "Stub!" );
}
@Override
public boolean onTransact(int code, Android.os.Parcel data, Android.os.Parcel reply, int flags) throws Android.os.RemoteException {
throw new RuntimeException( "Stub!" );
}
static final int TRANSACTION_getDeviceList = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_openDevice = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_getCurrentAccessory = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_openAccessory = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_setDevicePackage = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
static final int TRANSACTION_setAccessoryPackage = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
static final int TRANSACTION_hasDevicePermission = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
static final int TRANSACTION_hasAccessoryPermission = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 7);
static final int TRANSACTION_requestDevicePermission = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 8);
static final int TRANSACTION_requestAccessoryPermission = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 9);
static final int TRANSACTION_grantDevicePermission = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 10);
static final int TRANSACTION_grantAccessoryPermission = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 11);
static final int TRANSACTION_hasDefaults = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 12);
static final int TRANSACTION_clearDefaults = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 13);
static final int TRANSACTION_setCurrentFunction = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 14);
static final int TRANSACTION_setMassStorageBackingFile = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 15);
static final int TRANSACTION_allowUsbDebugging = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 16);
static final int TRANSACTION_denyUsbDebugging = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 17);
}
/* Returns a list of all currently attached USB devices */
public void getDeviceList(Android.os.Bundle devices)
throws Android.os.RemoteException;
/*
* Returns a file descriptor for communicating with the USB device. The
* native fd can be passed to usb_device_new() in libusbhost.
*/
public Android.os.ParcelFileDescriptor openDevice(
Java.lang.String deviceName) throws Android.os.RemoteException;
/* Returns the currently attached USB accessory */
public Android.hardware.usb.UsbAccessory getCurrentAccessory()
throws Android.os.RemoteException;
/*
* Returns a file descriptor for communicating with the USB accessory. This
* file descriptor can be used with standard Java file operations.
*/
public Android.os.ParcelFileDescriptor openAccessory(
Android.hardware.usb.UsbAccessory accessory)
throws Android.os.RemoteException;
/*
* Sets the default package for a USB device (or clears it if the package
* name is null)
*/
public void setDevicePackage(Android.hardware.usb.UsbDevice device,
Java.lang.String packageName, int userId)
throws Android.os.RemoteException;
/*
* Sets the default package for a USB accessory (or clears it if the package
* name is null)
*/
public void setAccessoryPackage(
Android.hardware.usb.UsbAccessory accessory,
Java.lang.String packageName, int userId)
throws Android.os.RemoteException;
/* Returns true if the caller has permission to access the device. */
public boolean hasDevicePermission(Android.hardware.usb.UsbDevice device)
throws Android.os.RemoteException;
/* Returns true if the caller has permission to access the accessory. */
public boolean hasAccessoryPermission(
Android.hardware.usb.UsbAccessory accessory)
throws Android.os.RemoteException;
/*
* Requests permission for the given package to access the device. Will
* display a system dialog to query the user if permission had not already
* been given.
*/
public void requestDevicePermission(Android.hardware.usb.UsbDevice device,
Java.lang.String packageName, Android.app.PendingIntent pi)
throws Android.os.RemoteException;
/*
* Requests permission for the given package to access the accessory. Will
* display a system dialog to query the user if permission had not already
* been given. Result is returned via pi.
*/
public void requestAccessoryPermission(
Android.hardware.usb.UsbAccessory accessory,
Java.lang.String packageName, Android.app.PendingIntent pi)
throws Android.os.RemoteException;
/* Grants permission for the given UID to access the device */
public void grantDevicePermission(Android.hardware.usb.UsbDevice device,
int uid) throws Android.os.RemoteException;
/* Grants permission for the given UID to access the accessory */
public void grantAccessoryPermission(
Android.hardware.usb.UsbAccessory accessory, int uid)
throws Android.os.RemoteException;
/*
* Returns true if the USB manager has default preferences or permissions
* for the package
*/
public boolean hasDefaults(Java.lang.String packageName, int userId)
throws Android.os.RemoteException;
/* Clears default preferences and permissions for the package */
public void clearDefaults(Java.lang.String packageName, int userId)
throws Android.os.RemoteException;
/* Sets the current USB function. */
public void setCurrentFunction(Java.lang.String function,
boolean makeDefault) throws Android.os.RemoteException;
/* Sets the file path for USB mass storage backing file. */
public void setMassStorageBackingFile(Java.lang.String path)
throws Android.os.RemoteException;
/*
* Allow USB debugging from the attached Host. If alwaysAllow is true, add
* the the public key to list of Host keys that the user has approved.
*/
public void allowUsbDebugging(boolean alwaysAllow,
Java.lang.String publicKey) throws Android.os.RemoteException;
/* Deny USB debugging from the attached Host */
public void denyUsbDebugging() throws Android.os.RemoteException;
}
そして、ユーザーIDを追加するコードを変更します。
...
service.setDevicePackage( usbDevice, YOUR_APP_PACKAGE_NAMESPACE, ai.uid );
....
ポップアップウィンドウにも同じ問題があり、クリックする人はいません。しかし、私は別のソリューションを見つけました(根ざしたデバイス用)。ポップアップは、クラスのAndroidUsbPermissionActivity)によって生成されます(UsbPermissionActivityはUsbSettingsManagerによって開始されます)。 Androidソースコードで何が起こっているのかを確認します。ここで良いのは、UsbPermissionActivityのバイトコードを操作してすべてのUsbDevicesを受け入れることができることです。ツールが必要ですそうするためにSmali/Baksmalihttps://code.google.com/p/smali/
adb pull path/to/SystemUI.apk
_を使用してコンピューターにコピーしますJava -jar baksmali.jar classes.dex
_でclasses.dexファイルを逆アセンブルしますファイルUsbPermissionActivityを見つけ、その中にある行を見つけます
invoke-virtual {p0}, Lcom/Android/systemui/usb/UsbPermissionActivity;->setupAlert()V
これをコメントアウトして、2つの新しい行を追加して変更します
#invoke-virtual {p0}, Lcom/Android/systemui/usb/UsbPermissionActivity;->setupAlert()V const/4 v0, 0x1 iput-boolean v0, p0, Lcom/Android/systemui/usb/UsbPermissionActivity;->mPermissionGranted:Z invoke-virtual {p0}, Lcom/Android/systemui/usb/UsbPermissionActivity;->finish()V
Java -jar smali.jar -o classes.dex out
_で組み立てますadb Push services.jar path/to/SystemUI.apk
_で置き換えるか、ファイルマネージャーapで機能しない場合Androidシステムをコンパイルするオプションがある場合、実行できないことは何もありません。
あなたは付け加えられます
public void onStart() {
super.onStart();
mPermissionGranted = true;
finish();
}
frameworks/base/packages/SystemUI/src/com/Android/systemui/usb/UsbPermissionActivity.Javaへ
許可確認ポップアップをバイパスします。
Androidは、この種の使用をすぐにサポートするようには設計されていません。個人的に、非対話型の使用のために、LinuxカーネルでUSBシリアルドライバーを使用し、Android USB APIをスキップすることを検討したいと思います。 Androidインストール-カーネル構成の変更および/またはモジュールのロード、デバイスファイルの作成、権限または所有者の設定、Unixグループの追加、およびAndroidアクセスを許可されたアプリの許可。
または、Androidソースを調べてユーザー確認を無効にすることができます。ただし、デバイス用のfrom-source Androidビルドがない場合、これはオープンソースAndroidをベンダーのデバイスで実行するように適応させるのは簡単ではない可能性があるため(誰かが既に、問題のデバイス)
根本的に、root/suアクセスはアプリケーション自体には適用されません-ルートハックが残したツールを実行する方法を知っているアプリケーションが、rootとして実行されるヘルパープログラムを起動できることを意味しますが、アプリケーション自体はそうではありません。できません。 rootを使用してシステムパーティションにアプリをインストールすると、特殊なAndroidパーミッションが得られる場合がありますが、USBに役立つものがあるかどうかを確認する必要があります。
事前に使用しているアクセサリをホワイトリストに登録することが最善の解決策になると思います。これを行うには、この場所にファイルusb_device_manager.xmlを追加する必要があります/ data/system/users/0
// 0はユーザーIDであることに注意してください。Androidにユーザーを追加しなかった場合は、おそらく0になりますが、このIDを適宜変更した場合
これはファイルがどのように見えるべきであるかです:
<settings>
<preference package="<PACKAGE NAME OF APP YOU WANT TO START ON CONNECTIONCTION>">
<usb-accessory manufacturer="<NAME OF MANUFECTURER LIKE ONE REGISTERED IN meta-data in the manifest>" model="<MODEL NAME LIKE ONE REGISTERED IN meta-data in the manifest>" version="<VERSION LIKE ONE REGISTERED IN meta-data in the manifest>" />
</preference>
このようなボードの場合 http://www.embeddedartists.com/products/app/aoa_kit.php
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<settings>
<preference package="com.embeddedartists.aoa">
<usb-accessory manufacturer="Embedded Artists AB" model="AOA Board - Basic" version="1.0" />
</preference>
Android開発者のドキュメントによれば、アプリがマニフェストインテントフィルターを介して開始されると、接続されたUSBデバイスへのアクセス許可が既にあります。おそらくこのアプローチを試して、他のアプリもデバイスと通信することを防ぐために、使用するデバイス。
http://developer.Android.com/guide/topics/connectivity/usb/Host.html#permission-d の「注」を参照してください。
これを達成する1つの方法は、これが実際に確認を取り除くわけではないことに注意してください。checkbox
の位置を特定し、Androidと同等のロボットクラスを選択してからOK
を選択します。バックグラウンドで実行されるアプリケーションを記述できます。 、特にこの目的のために。
Androidソースコードにアクセスできる場合、許可ダイアログを無効にするために必要なコードは次のとおりです。
上記のコードの更新により、使用できる構成オプションが作成されます。または、代わりにmDisablePermissionDialogs
の代わりに値trueを使用してハードコーディングして、許可ダイアログを無効にすることができます。
services/usb/Java/com/Android/server/usb/UsbSettingsManager.Java