diff --git a/client/build.gradle b/client/build.gradle index afe59b6e0833c6e330126def80cd28ac1a9d8696..e94f4b1d0f0bedefa8991c6e1e573490692aab8c 100644 --- a/client/build.gradle +++ b/client/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'com.android.library' +apply plugin: 'witness' android { compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION) @@ -14,10 +15,20 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } } + lintOptions { + abortOnError false + } } dependencies { compile project(path: ':routerjars', configuration: 'client') + compile 'com.android.support:support-v4:19.1.0' +} + +dependencyVerification { + verify = [ + 'com.android.support:support-v4:3f40fa7b3a4ead01ce15dce9453b061646e7fe2e7c51cb75ca01ee1e77037f3f', + ] } android.libraryVariants.all { variant -> diff --git a/client/src/main/java/net/i2p/android/ui/I2PAndroidHelper.java b/client/src/main/java/net/i2p/android/ui/I2PAndroidHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..9a62c82c7b3dc0475e7dd5715aeb7e52164d4411 --- /dev/null +++ b/client/src/main/java/net/i2p/android/ui/I2PAndroidHelper.java @@ -0,0 +1,156 @@ +package net.i2p.android.ui; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.ComponentName; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.IBinder; +import android.os.RemoteException; + +import net.i2p.android.lib.client.R; +import net.i2p.android.router.service.IRouterState; + +/** + * @author str4d + * @since 0.2 + */ +public class I2PAndroidHelper { + public static final String URI_I2P_ANDROID = "net.i2p.android"; + public static final String URI_I2P_ANDROID_DONATE = "net.i2p.android.donate"; + public static final String URI_I2P_ANDROID_LEGACY = "net.i2p.android.legacy"; + + public static final int REQUEST_START_I2P = 9857; + + private Context mContext; + private boolean mTriedBindState; + private IRouterState mStateService; + + public I2PAndroidHelper(Context context) { + mContext = context; + } + + /** + * Try to bind to I2P Android. Call this in Activity.onStart() + */ + public void bind() { + Intent i2pIntent = new Intent(IRouterState.class.getName()); + try { + mTriedBindState = mContext.bindService( + i2pIntent, mStateConnection, Context.BIND_AUTO_CREATE); + } catch (SecurityException e) { + // Old version of I2P Android (pre-0.9.13), cannot use + mStateService = null; + mTriedBindState = false; + } + } + + /** + * Unbind from I2P Android. Call this in Activity.onStop(); + */ + public void unbind() { + if (mTriedBindState) + mContext.unbindService(mStateConnection); + mTriedBindState = false; + } + + private ServiceConnection mStateConnection = new ServiceConnection() { + public void onServiceConnected(ComponentName className, + IBinder service) { + mStateService = IRouterState.Stub.asInterface(service); + } + + public void onServiceDisconnected(ComponentName className) { + // This is called when the connection with the service has been + // unexpectedly disconnected -- that is, its process crashed. + mStateService = null; + } + }; + + /** + * Check if I2P Android is installed. + * @return true if I2P Android is installed, false otherwise. + */ + public boolean isI2PAndroidInstalled() { + return isAppInstalled(URI_I2P_ANDROID) || + isAppInstalled(URI_I2P_ANDROID_DONATE) || + isAppInstalled(URI_I2P_ANDROID_LEGACY); + } + + private boolean isAppInstalled(String uri) { + PackageManager pm = mContext.getPackageManager(); + boolean installed; + try { + pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES); + installed = true; + } catch (PackageManager.NameNotFoundException e) { + installed = false; + } + return installed; + } + + /** + * Show dialog - install from market or F-Droid. + * @param activity + */ + public void promptToInstall(final Activity activity) { + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.setTitle(R.string.install_i2p_android) + .setMessage(R.string.you_must_have_i2p_android) + .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialogInterface, int i) { + String uriMarket = activity.getString(R.string.market_i2p_android); + Uri uri = Uri.parse(uriMarket); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + activity.startActivity(intent); + } + }) + .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialogInterface, int i) { + } + }); + builder.show(); + } + + /** + * Check if I2P Android is running. If {@link net.i2p.android.ui.I2PAndroidHelper#bind()} + * has not been called previously, this will always return false. + * @return true if I2P Android is running, false otherwise. + */ + public boolean isI2PAndroidRunning() { + if (mStateService == null) + return false; + + try { + return mStateService.isStarted(); + } catch (RemoteException e) { + // TODO: log + return false; + } + } + + /** + * Show dialog - request that I2P Android be started. + * @param activity + */ + public void requestI2PAndroidStart(final Activity activity) { + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.setTitle(R.string.start_i2p_android) + .setMessage(R.string.would_you_like_to_start_i2p_android) + .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Intent i = new Intent("net.i2p.android.router.START_I2P"); + activity.startActivityForResult(i, REQUEST_START_I2P); + } + }) + .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + } + }); + builder.show(); + } +} diff --git a/client/src/main/res/values/strings.xml b/client/src/main/res/values/strings.xml index f00bf74f9364c17995109cdd1eedb4a00f1b8779..37d5b9270cbd67cbb5858d83e7951b1c7f1ff573 100644 --- a/client/src/main/res/values/strings.xml +++ b/client/src/main/res/values/strings.xml @@ -1,3 +1,10 @@ <resources> - <string name="app_name">I2P Android client</string> + <string name="app_name" translatable="false">I2P Android client</string> + <string name="yes">Yes</string> + <string name="no">No</string> + <string name="install_i2p_android">Install I2P Android?</string> + <string name="you_must_have_i2p_android">You must have I2P Android installed and running. Would you like to install it?</string> + <string name="market_i2p_android" translatable="false">market://search?q=pname:net.i2p.android</string> + <string name="start_i2p_android">Start I2P Android?</string> + <string name="would_you_like_to_start_i2p_android">It appears that I2P Android is not running. Would you like to start it?</string> </resources>